转载请注明原文地址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 }
BZOJ4521

相关文章: