hdu 3652 数位DP 进阶
2015-12-12 16:31
387 查看
dp[i][j][k] i表示数字位数(可以包含前导0,即00054也算5位数),j表示除13的余数,k表示状态(状态2为含有“13”,状态1为不含13末尾为1,否则状态为0) dp表示满足上述i、j、k的数字的个数。
结合记忆化搜索(不用记忆化搜索其实也可以)。
结合记忆化搜索(不用记忆化搜索其实也可以)。
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define MS(x,y) memset(x,y,sizeof(x)) #define pi acos(-1.0) using namespace std; void fre(){freopen("t.txt","r",stdin);} typedef long long LL; typedef unsigned long long ULL; const int mod = 1e9 + 7; const int inf = (1<<63)-1; const double eps = 1e-8; int digit[11],len; int dp[15][15][5]; void getnum(int n) { len = 0; while(n!=0) { digit[++len] = n%10; n/=10; } } int dfs(int top,int mod,int st,bool flag)//top表示第几位数,mod表示余数,st表示状态。flag表示计算的是不是完整的top位数。如 n=111 时,我们计算的三位数不是完整的三位数,有一个上界111,所以不能用dp中储存的数据。而且也有一些别的限制,详见代码。 { if(top ==0) return mod == 0 && st == 2;//top=0 表示这个数搜完了,那么mod ==0 st==2 表示这个数满足题意,返回1. if(!flag && dp[top][mod][st] != -1) return dp[top][mod][st]; int i,ans = 0; int max_digit = flag?digit[top]:9;//如果flag=1即有上界,那么取上界 for(i = 0; i <= max_digit; ++i) { int nhave,nmod; nmod = (mod*10+i)%13;//计算新的余数 nhave = st;//计算新的状态 if(st == 0 && i == 1) nhave = 1; if(st == 1 && i != 1) nhave = 0; if(st == 1 && i == 3) nhave = 2; ans+=dfs(top-1,nmod,nhave,flag&&i==max_digit); } if(!flag) dp[top][mod][st] = ans;//如果是完整的top位数,那么保存下来(记忆化搜索) return ans; } int main() { //fre(); int n; MS(dp,-1);//-1表示未访问 while(~scanf("%d",&n)) { getnum(n); printf("%d\n",dfs(len,0,0,1)); } return 0; }
相关文章推荐
- 被需要,才是最极致的幸福
- MIFARE系列7《安全》
- Delphi Edit输入+号(加号),不允许显示输入符号,清空Edit,显示事件
- 给结构赋值和显示
- Windows 10 优化方案
- 详解光纤光缆、网线、电缆的区别
- matlab figure edit 加标注
- Life
- 236.Lowest Common Ancestor of a Binary Tree
- Daily Scrum 12.12
- fork函数和vfork函数的区别--19
- 使用memcache实现锁操作
- 进程kill的方法
- MFC背景颜色
- x264预设类参数详解
- android内存管理(二)
- 深入理解Java:注解(Annotation)--注解处理器
- ERROR: Error installing json:The 'json' native gem requires installed build tools.
- lua-luaStudio安装
- eclipse 远程调试