bzoj 1026 [ SCOI2009 ] windy数 —— 数位DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1026
蛮简单的数位DP,预处理 f[i][j] 表示 i 位数,以 j 开头的 windy 数个数;
但不明白为什么最后一位拿出来特判 ret++ 不对,而写在循环里,特判 i==1 就对了...
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a,b,f[15][15],num[15]; int abb(int x){return (x>0)?x:-x;} int getnum(int x) { int cnt=0; while(x)num[++cnt]=x%10,x/=10; return cnt; } void init() { int mx=getnum(b); for(int i=0;i<=9;i++)f[1][i]=1; for(int i=2;i<=mx;i++) for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) if(abb(j-k)>=2)f[i][j]+=f[i-1][k]; } int calc(int x) { int mx=getnum(x),ret=0; for(int i=1;i<mx;i++) for(int j=1;j<=9;j++)ret+=f[i][j]; for(int j=1;j<num[mx];j++)ret+=f[mx][j]; for(int i=mx-1,pre;i;i--) { pre=num[i+1]; if(i!=1) { for(int j=0;j<num[i];j++) if(abb(pre-j)>=2)ret+=f[i][j]; } if(i==1)//AC { for(int j=0;j<=num[i];j++) if(abb(pre-j)>=2)ret+=f[i][j]; } if(abb(num[i]-pre)<2)break;//! } // if(mx==1||abb(num[1]-num[2])>=2)ret++;//WA // if(abb(num[1]-num[2])>=2)ret++;//WA return ret; } int main() { scanf("%d%d",&a,&b); init(); printf("%d\n",calc(b)-calc(a-1)); return 0; }
分类:
动规 - 数位DP
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 你所不知道的 C/C++ 宏知识
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· SQL Server 内存占用高分析
· .NET Core GC计划阶段(plan_phase)底层原理浅谈
· .NET开发智能桌面机器人:用.NET IoT库编写驱动控制两个屏幕
· 我干了两个月的大项目,开源了!
· 推荐一款非常好用的在线 SSH 管理工具
· 千万级的大表,如何做性能调优?
· 盘点!HelloGitHub 年度热门开源项目
· Phi小模型开发教程:用C#开发本地部署AI聊天工具,只需CPU,不需要GPU,3G内存就可以运行,