数位dp 不要62
纯纯数位dp板子,可以顺着思路下来。
设状态为 \(dp[i][j]\) 为第 \(i\) 位是 \(j\) 的可能情况数。
枚举位数,这位的数,低一位的数,将每一位的组合可能存下来,但要把这位是 4 与这位是 6 低一位是 2 的情况排除掉。
void init(){ dp[0][0]=1; for(int i=1;i<=8;i++){ for(int j=0;j<=9;j++){ if(j==4){ continue; } for(int k=0;k<=9;k++){ if((j==6&&k==2)){ continue; } dp[i][j]+=dp[i-1][k]; } } } }
然后进行计算,将每一位存下来,循环 0-a[i]-1,因为a[i]不能直接取全部情况,注意这时要将这位是2高一位6的情况排除掉,这个可以思考思考就可以了。如果出现哪一位4和62的话直接跳出,因为后面一定就不会取到。
ll dig(int x){ int cnt=0; ll sum=0; while(x){ a[++cnt]=x%10; x/=10; } a[cnt+1]=-1; for(int i=cnt;i>=1;i--){ for(int j=0;j<a[i];j++){ if(j==2&&a[i+1]==6){ continue; } sum+=dp[i][j]; } if(a[i]==4||(a[i+1]==6&&a[i]==2)){ break; } } return sum; }
这样计算时要r+1,因为最后一位总是取不到,所以要多打个1就可以了。
#include<bits/stdc++.h> using namespace std; #define ll long long int n,m; ll dp[15][15]; int a[15]; void init(){ dp[0][0]=1; for(int i=1;i<=8;i++){ for(int j=0;j<=9;j++){ if(j==4){ continue; } for(int k=0;k<=9;k++){ if((j==6&&k==2)){ continue; } dp[i][j]+=dp[i-1][k]; } } } } ll dig(int x){ int cnt=0; ll sum=0; while(x){ a[++cnt]=x%10; x/=10; } a[cnt+1]=-1; for(int i=cnt;i>=1;i--){ for(int j=0;j<a[i];j++){ if(j==2&&a[i+1]==6){ continue; } sum+=dp[i][j]; } if(a[i]==4||(a[i+1]==6&&a[i]==2)){ break; } } return sum; } int main(){ ios::sync_with_stdio(false); init(); while(1){ cin>>n>>m; if(n==0&&m==0){ break; } cout<<dig(m+1)-dig(n)<<"\n"; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」