bzoj 3679 數字之積

2021-08-15 12:21:17 字數 1188 閱讀 4627

乙個數x各個數字上的數之積記為f(x) 《不含前導零》 求[l,r)中滿足0< f(x)<= n的數的個數

(我的做法應該在這道題裡面是最差的了,並且**應該是最醜的了)

這道題的新奇的地方實際是n的範圍,不然其實上是一道大水題了。但其實也只需要改動一點小地方,因為我們發現數字之積是2,3,5,7的倍數,不會有其他的質因子參與進來。所以我們定義乙個五維陣列,f[i][s1][s2][s3][s4],i為列舉到的位數(從後往前),s1~s4則分別表示列舉到現在的2,3,5,7各個數的指數。然後這道題就迎刃而解了。(陣列一定不要因為保險而開過大,不然會mle,不要問我怎麼知道的)

#include

#include

#include

#include

#include

using

namespace

std;

int n,a[19];

long

long n1[55],n2[37],n3[19],n4[19],f[19][55][37][19][19];

bool wy(int s1,int s2,int s3,int s4)

long

long dfs(int pos,int s1,int s2,int s3,int s4,bool limt,bool lead)

if(wy(s1,s2,s3,s4)==false)return

0; if(limt==false && lead==false && f[pos][s1][s2][s3][s4]!=-1)return f[pos][s1][s2][s3][s4];

int up=9;long

long ans=0;

if(limt==true)up=a[pos];

for(int i=0;i<=up;i++)

if(limt==false && lead==false)f[pos][s1][s2][s3][s4]=ans;

return ans;

}long

long solve(long

long x)

memset(f,-1,sizeof(f));

return dfs(pos,0,0,0,0,true,true);

}int main()

BZOJ 3679 數字之積

人生第一道數字dp,首先對於每位數的乘積,有乙個很顯然的轉移方程 d i j 表示 i 位數乘積為 j的方案數,則有 d i j 1 k 9 k j d i 1 k j 然而我們發現j可能很大,但經過實驗發現只有5000餘個,於是我們可以吧第二維下標換成在數表中的排名,單個遞推就可做了 對於區間 1...

BZOJ3679 數字之積

3679 數字之積 time limit 10 sec memory limit 128 mb submit 415 solved 195 submit status discuss description 乙個數x各個數字上的數之積記為f x 不含前導零 求 l,r 中滿足0 f x n的數的個數...

bzoj 3679 數字之積

乙個數x各個數字上的數之積記為 f x 不含前導零 求 l,r 中滿足 0的數的個數 最後 f x 可以拆分成2,3,5,7的乘積,我們就將 2,3,5,7 壓進狀態,然後就是基礎的數字dp,分是否嚴格小於兩種狀態轉移即可 具體實現需要一些技巧 預處理出每乙個數含有 2,3,5,7 的個數 預處理出...