惊奇地发现今天居然和dalao的题单重了不少23333333333333
这是我第一次做数位dp,感觉这个题目还是比较兹磁的
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int l,r,dp[20][15],a[20]; int dfs(int pos,int las,int fl,bool flag)//pos是当前位置,las是上次选的那个数,fl判断上次选的数是否为6,flag判断pos位上是否有枚举限制 {if(pos==0)//答案成立,返回1 return 1;if(!flag&&dp[pos][las]!=-1)//如果flag==1的时候也返回,那么像213的时候会使答案偏大 return dp[pos][las];int ding=(flag)?a[pos]:9;//判断这一位上是否有限制最大能枚举的数 int re=0;for(int i=0;i<=ding;i++){if(i==4||(las==6&&i==2))//不能出现4或者62 continue;re+=dfs(pos-1,i,i==6,flag&&i==a[pos]);}if(!flag)//如果flag==1说明这一位有限制,并不完全将第pos位上一次选的las的状态完全包含,所以不能赋值 dp[pos][las]=re;return re; } int solve(int x) {int pos=0;while(x>0)//先拆分成一位位的数字 a[++pos]=x%10,x/=10;return dfs(pos,-1,0,1);//flag初始设为0是因为数位长度+1位确实是0 } int main() {memset(dp,-1,sizeof(dp));//每次输入的只是不同的数据范围,但是不会影响dp数组的答案,所以只初始化一遍就好 while(~scanf("%d%d",&l,&r)){if(l==0&&r==0)break;printf("%d\n",solve(r)-solve(l-1));//l也被包含在答案区间一部分 } }