hdu3652 B-number 数位DP
2013-09-19 21:39
288 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3652
题意就是求区间内能被13整除并且包含”13“的数字的个数
感觉是比较中等的数位DP题目
我用的记忆化的方式做的
定义dp[len][mod][mark];
其中len表示当前正在处理的位数或可以理解为还有len位需要处理,mod表示当前的总的余数(即从最高位到len位时所计算得到的余数)
mark起标记作用
mark==0表示从最高位到i位还没有出现”13“;
mak==1表示从最高位到i位没有出现”13“,但第i位为1
mark==2表示从最高位到i位包含”13“
具体实现如下:
题意就是求区间内能被13整除并且包含”13“的数字的个数
感觉是比较中等的数位DP题目
我用的记忆化的方式做的
定义dp[len][mod][mark];
其中len表示当前正在处理的位数或可以理解为还有len位需要处理,mod表示当前的总的余数(即从最高位到len位时所计算得到的余数)
mark起标记作用
mark==0表示从最高位到i位还没有出现”13“;
mak==1表示从最高位到i位没有出现”13“,但第i位为1
mark==2表示从最高位到i位包含”13“
具体实现如下:
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> using namespace std; int n; int len; int bit[40]; int dp[40][14][4]; void init(int n) { memset(dp,-1,sizeof(dp)); len=0; while(n) { bit[++len]=n%10; n/=10; } } int dfs(int len,int mod,int mark,int flag) { int sum=0; if(len==0) return mod==0 && mark==2; if(flag && dp[len][mod][mark]>=0) return dp[len][mod][mark]; int tmp=flag?9:bit[len]; for(int i=0;i<=tmp;i++) { int Mod=(mod*10+i)%13; int Mark=mark; if(mark!=2 && i!=1) Mark=0; if(mark!=2 && i==1) Mark=1; if(mark==1 && i==3 )Mark=2; sum+=dfs(len-1,Mod,Mark,flag||i<tmp); } if(flag) dp[len][mod][mark]=sum; return sum; } int main() { while(scanf("%d",&n)!=EOF) { init(n); cout<<dfs(len,0,0,0)<<endl; } return 0; }
相关文章推荐
- hdu3652 B-number (数位DP)
- [暑假集训--数位dp]hdu3652 B-number
- HDU3652_B-number_数位DP&记忆化搜索
- Hdu3652B-number数位dp
- HDU3652 B-number 数位DP
- hdu3652 B-number(数位DP)
- hdu3652---B-number(数位dp)
- [HDU3652]B-number && 数位DP
- hdu3652 B-number 数位dp
- hdu3652 B-number 数位dp
- HDU3652B-number(数位DP)
- 【HDU3652】B-number-数位DP
- 【hdu3652】【数位DP】B-number
- [hdu3652]B-number(数位dp)
- hdu3652 B-number[数位dp]
- hdu3652 B-number(数位dp+dfs)
- hdu3652B-number(数位dp)
- HDU3652:B-number(数位dp + 同余)
- 【数位DP】HDU3652[B-number]题解
- hdu3652 A-B number 数位DP