hdu 3652(数位dp 记忆化搜索方法)
2014-07-22 11:13
423 查看
题目链接:点击打开链接
//数位dp 记忆化搜索方法 #include<stdio.h> #include<string.h> int digit[20];//存各位上的数字 int dp[20][3][13];//数位 前缀标记 余数 int l; int dfs(int pre,int pos,int mod,int doing) { if(pos==-1)//搜到结尾 { if(mod==0&&pre==2) return 1;//余数为零 并且包含13 返回1说明这种状态合法结果需要加1 return 0; } if(!doing&&dp[pos][pre][mod]!=-1) return dp[pos][pre][mod];//以前标记过的状态直接返回 int i,End,ans; End=doing?digit[pos]:9;//判断枚举上界 ans=0; for(i=0;i<=End;i++) { if(pre==2)//如果前缀包含13 枚举后面的位时前缀一定包含13 ans+=dfs(2,pos-1,(mod*10+i)%13,doing && i==End); else if(pre==1&&i==3)//如果前一位是1 当前位时3 则枚举以后位时前缀包含13 { ans+=dfs(2,pos-1,(mod*10+i)%13,doing && i==End); } else if(i==1)//如果当前位是1 则枚举下一位时 前一位是1 { ans+=dfs(1,pos-1,(mod*10+i)%13,doing && i==End); } else// 其他情况为前缀不包含13 且前一位不为1 的情况 { ans+=dfs(0,pos-1,(mod*10+i)%13,doing && i==End); } } if(!doing) dp[pos][pre][mod]=ans; return ans; } int solve(int n) { l=0; memset(digit,0,sizeof(digit)); memset(dp,-1,sizeof(dp)); while(n>0)//把n的各位上的数存到digit中 { digit[l++]=n%10; n=n/10; } return dfs(0,l-1,0,1); } int main() { int n; while(scanf("%d",&n)!=EOF) { printf("%d\n",solve(n)); } return 0; }
相关文章推荐
- HDU 3555 Bomb (数位DP-记忆化搜索模板)
- HDU 4352 XHXJ's LIS(*数位DP 记忆化搜索 待整理)
- LightOJ 1140 How Many Zeroes?(数位dp 记忆化搜索方法)
- HDU 3555 Bomb (数位DP-记忆化搜索模板)
- 两个数位DP,记忆化搜索版(HDU 3652 HDU 3709)
- hdu 4293 Groups dp 记忆化搜索
- HDU 5001 概率DP || 记忆化搜索
- hdu 2067 简单记忆化搜索
- HDU 2364 (记忆化BFS搜索)
- HDU 1016 Prime Ring Problem DFS + 记忆化搜索
- HDU1978 记忆化搜索
- hdu--1978--记忆化深度搜索||递推
- HDU 4085 Peach Blossom Spring 记忆化搜索枚举子集 斯坦纳树
- hdu 1142 记忆化搜索
- HDU--杭电--1208--Pascal's Travels--记忆化搜索--这个也和机器人那个一样算半个DP吧
- hdu 5012 Dice 记忆化搜索
- HDU 3811 Permutation 记忆化搜索 状态压缩 DP
- HDU--杭电--1978--How many ways--记忆化搜索--这个鸟东西应该能算半个DP吧
- hdu 1978(记忆化DFS搜索)
- HDU 2653 (记忆化BFS搜索+优先队列)