题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2089
题意:中文,不解释
题解:dp[i][j]表示当前第i位的前一个数为j,然后记忆化dfs,注意的是给的是一个区间,容斥完后要处理大的那个数
1 #include<cstdio> 2 #include<cstring> 3 #define F(i,a,b) for(int i=a;i<=b;i++) 4 5 int dp[10][10],n,m,dig[7],len,ans1,tmp,fg,pre; 6 7 int dfs(int pos,int pre,bool inf){ 8 if(!pos)return !inf; 9 if(!inf&&dp[pos][pre]!=-1)return dp[pos][pre]; 10 int end=(inf?dig[pos]:9),ans=0; 11 F(i,0,end)if(!(pre==6&&i==2||i==4))ans+=dfs(pos-1,i,inf&&(i==end)); 12 if(!inf)dp[pos][pre]=ans; 13 return ans; 14 } 15 16 int main(){ 17 memset(dp,-1,sizeof(dp)); 18 while(~scanf("%d%d",&n,&m),n+m){ 19 for(len=0;n;)dig[++len]=n%10,n/=10; 20 ans1=dfs(len,0,1); 21 for(tmp=m,fg=1,pre=-1;tmp;pre=tmp%10,tmp/=10) 22 if(tmp%10==4)fg=0;else if(tmp%10==6&&pre==2)fg=0; 23 for(len=0;m;)dig[++len]=m%10,m/=10; 24 printf("%d\n",dfs(len,0,1)+fg-ans1); 25 } 26 return 0; 27 }