BZOJ 3679 數字之積 數字DP

2021-08-10 07:12:40 字數 1506 閱讀 4369

description

乙個數x各個數字上的數之積記為f(x) 《不含前導零》

求[l,r)中滿足0

這題資料非常非常水……我的錯誤**幾乎一半資料範圍都過不了都ac了……好在fyc大神發現我的**錯了,看了半天,終於明白了。有這幾個錯誤:1、用log來比較數的大小。這樣是十分不精確的,平常不推薦使用。2、陣列開小。一開始想當然地以為陣列的範圍開到n的範圍就好了,但是後來發現在轉移的過程中很容易就超過這個範圍了,所以陣列要開大,或者在轉移的時候判斷一下也可以。還有這題我被卡了空間,一定要滾動第一維才能過……網上好像沒人寫我這種數字dp,不過我只會寫這種……

#include

using

namespace

std;

#define ll long long

#define pa pair

const

int inf=2147483647;

ll read()

while(ch>='0'&&ch<='9')

return x*f;

}int n;

ll l,r;

ll num=;

struct nodelist[800000];

int len=0;

int a[20],b[20];

ll f[2][40][25][20][15][2][2],pow[4][35];

//0沒有小於 1已經小於

//0可以填0 1不能填0

ll solve(ll x)

f[now][a+c[2]][b+c[3]][c+c[5]][d+c[7]][(!j1&&l==a[i+1])?0:1][(!j2&&!l)?0:1]+=t;}}

}}

for(int i=1;i<=len;i++)

for(int j1=0;j1<2;j1++)

re+=f[now][list[i].a[0]][list[i].a[1]][list[i].a[2]][list[i].a[3]][j1][1];

return re;

}int ll[4];

int main()

else pow[i][j]=pow[i][j-1]*num[i];

}for(int i=0;i<=ll[0]&&pow[0][i]<=n;i++)

for(int j=0;j<=ll[1]&&pow[0][i]*pow[1][j]<=n;j++)

for(int k=0;k<=ll[2]&&pow[0][i]*pow[1][j]*pow[2][k]<=n;k++)

for(int l=0;l<=ll[3]&&pow[0][i]*pow[1][j]*pow[2][k]*pow[3][l]<=n;l++)

list[++len].a[0]=i,list[len].a[1]=j,list[len].a[2]=k,list[len].a[3]=l;

printf("%lld",solve(r-1)-solve(l-1));

}

bzoj3679 數字之積 數字dp

裸的數字dp,豪爺講課的時候秒掉了,但是後來發現會mle,於是我們做這麼一件事,考慮數字的乘積一定是2 3 5 7的多少次冪之積,於是我們對於乙個n,把可行的數字拿出來排個序編個號就好了,表示不會用新學的這種數字dp處理前導0,果斷滾回原來的dp。include include include in...

bzoj 3679 數字之積 數字dp

乙個數x各個數字上的數之積記為f x 不含前導零 求 l,r 中滿足0input 第一行乙個數n 第二行兩個數l r output 乙個數,即滿足條件的數的個數 sample input 5 19 22 sample output hint 100 0很容易想到數字dp,但是因為n太大,無法直接做。...

BZOJ 3679 數字之積 數字DP

還是記憶化搜尋就行,但是要用 map 記憶化。見 include include include define r register int define ll long long using namespace std namespace luitaryi ll n,l,r,num 19 len,...