| [数位DP] |
| 运用记忆化搜索来对每一位枚举, |
| 一般需要枚举以下几种参数: |
| id:枚举到第几位。 |
| x:当前位是否与num[id]相等,即当前是否为上限。 |
| zero:是否有前导0(前导0---签到题爆0) |
| sum:其他题目需要的(如luogu P2602 [ZJOI2010] 数字计数就是求数量) |
| 1. |
| luogu P2602 [ZJOI2010] 数字计数 |
| accoders 2201【一本通提高数位动态规划】数字计数 |
| 思路: |
| 要求统计从l到r 每个数字重复了多少遍, |
| 对其进行记忆化搜索,计算出从0到当前的数字有多少个, |
| 然后运用神似前缀和的方法求出总数即可。 |
| code: |
| #include<bits/stdc++.h> |
| using namespace std; |
| #define int long long |
| int dp[20][2][20][2]; |
| int num[20]; |
| int dfs(int id,int x,int sum,int zero,int number){ |
| int ans=0; |
| if(id==0){ |
| return sum; |
| } |
| if(dp[id][x][sum][zero]!=-1){ |
| return dp[id][x][sum][zero]; |
| } |
| for(int i=0;i<10;i++){ |
| if(!x&&i>num[id]){ |
| break; |
| } |
| ans+=dfs(id-1,x||(i<num[id]),sum+((!zero||i)&&(i==number)),zero&&(i==0),number); |
| } |
| dp[id][x][sum][zero]=ans; |
| return ans; |
| } |
| int f(int x,int number){ |
| int l=0; |
| while(x){ |
| num[++l]=x%10; |
| x/=10; |
| } |
| memset(dp,-1,sizeof(dp)); |
| return dfs(l,0,0,1,number); |
| } |
| signed main(){ |
| int a,b; |
| cin>>a>>b; |
| for(int i=0;i<10;i++){ |
| cout<<f(b,i)-f(a-1,i)<<" "; |
| } |
| return 0; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效