看到某大佬AC,本蒟蒻也决定学习一下玄学的数位$dp$
(以上是今年3月写的话(叫我鸽神$qwq$))
思路:数位$DP$
提交:2次
题解:(见代码)
#include<cstdio> #include<iostream> #include<cstring> #define R register int using namespace std; int a,b,f[12][10],num[11]; //f[i][j]搜到第i位,前一位是j,且没有上界标记的方案数 inline int max(int a,int b){return a>b?a:b;} inline int abs(int x){return x>0?x:-x;} int dfs(int l,bool ul,bool ck,int lst) {//l位数,ul上界标记,ck前导零标记,lst上一位 if(!l) return 1; if(!ul&&(~f[l][lst])) return f[l][lst];//记忆化 R mx=ul?num[l]:9,cnt=0;//mx是上界 for(R i=0;i<=mx;++i) { if(abs(lst-i)<2) continue;//差小于2 if(ck&&i==0) cnt+=dfs(l-1,ul&&i==mx,true,-2);//若一直是前导零 else cnt+=dfs(l-1,ul&&i==mx,false,i); } return ul||ck?cnt:f[l][lst]=cnt; } inline int solve(int x) { R len=0; memset(f,0xff,sizeof(f)); for(;x;x/=10) num[++len]=x%10;//分解每一位 return dfs(len,true,true,-2); } signed main() { scanf("%d%d",&a,&b); printf("%d ",solve(b)-solve(a-1));//前缀和减一下 }
2019.07.18