转载请注明原文地址http://www.cnblogs.com/LadyLex/p/8490222.html
之前学数位dp的时候底子没打扎实
虚的要死
这次正好有时间……刷了刷之前没做的题目
感觉自己脑洞不太够……比较经典的题或者见过的类似模型就能自己推出来,但是没有见过的模型就虚的要死(比如二进制数位DP)
感谢WQ的帮助,让我对数位DP的理解逐渐加深
那么我们总结一下这次做的题目……
bzoj4521
记忆化搜索即可,水爆
1 #include <cstring> 2 #include <cstdio> 3 using namespace std; 4 #define RG register 5 #define LL long long 6 int bin[15],cnt; 7 LL poww[15],f[12][10][3][3][2][2]; 8 inline int min(int a,int b){return a<b?a:b;} 9 inline int max(int a,int b){return a>b?a:b;} 10 inline LL dfs(int st,int pre,int comb,int maxcomb,bool have8,bool have4,bool limit) 11 { 12 if(st==0)return maxcomb==3; 13 if(!limit&&f[st][pre][comb][maxcomb][have8][have4]!=-1) 14 return f[st][pre][comb][maxcomb][have8][have4]; 15 LL ret=0; 16 RG int i,tmp,lim=(limit)?bin[st]:10; 17 for(i=0;i<lim;++i) 18 { 19 tmp=min((pre==i)?comb+1:1,3); 20 if(i==4) 21 { 22 if(!have8)ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),0,1,0); 23 } 24 else if(i==8) 25 { 26 if(!have4)ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),1,0,0); 27 } 28 else ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),have8,have4,0); 29 } 30 if(limit) 31 { 32 tmp=min((pre==i)?comb+1:1,3); 33 if(i==4) 34 { 35 if(!have8)ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),0,1,1); 36 } 37 else if(i==8) 38 { 39 if(!have4)ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),1,0,1); 40 } 41 else ret+=dfs(st-1,i,tmp,max(tmp,maxcomb),have8,have4,1); 42 } 43 if(!limit)f[st][pre][comb][maxcomb][have8][have4]=ret; 44 return ret; 45 } 46 inline LL calc(LL len) 47 { 48 LL ret=0;cnt=0; 49 while(len)bin[++cnt]=len%10,len/=10; 50 for(RG int i=1;i<bin[11];++i)ret+=dfs(10,i,1,1,i==8,i==4,0); 51 return ret+dfs(10,bin[11],1,1,bin[11]==8,bin[11]==4,1); 52 } 53 int main() 54 { 55 LL l,r,ans;RG int i; 56 for(poww[0]=i=1;i<=12;++i)poww[i]=poww[i-1]*9; 57 scanf("%lld%lld",&l,&r); 58 memset(f,-1,sizeof(f)),ans=calc(r); 59 if(l>1e10)ans-=calc(l-1); 60 printf("%lld\n",ans); 61 }