HDU 3555 Bomb 数位DP
2015-08-10 17:22
411 查看
一:题意
给定一个N,要求你求出[0,N]内所有含有49的数字个数,其中N
(1 <= N <= 2^63-1)。
二:解析
1,对于这一类数位dp,需要扫描[0,N]区间所有数的每一位,为了避免对每一个数取出每位数。我们利用数组来存储区间[0,N]的每一个数,数组的长度为N的位数 x (即最大位数) ,对于没有x位的数来说,我们在前位数面补0即可,这样我们只要扫描该最长数组,枚举数组每一位可能取的数(0,1,,,,9),就可以扫描区间[0,N]所有数字。
2,dp数组含义
dp[len][0] 表示前驱为非4,长度为len里面 “49” 数的个数。
dp[len][1] 表示前驱为4,长度为len里面 “49” 数的个数。
注意:
这些记录都是在没最大数限制的情况下记录的,所以在调用时必须不受大数限制(即前驱不是最大值)。这是因为我们每次输入的最大值是不同的,所以受最大值限制的数也会不同(即没有通用性),只要没受最大数限制的那些数对所有的N都可用(即具有通用性)。
给定一个N,要求你求出[0,N]内所有含有49的数字个数,其中N
(1 <= N <= 2^63-1)。
二:解析
1,对于这一类数位dp,需要扫描[0,N]区间所有数的每一位,为了避免对每一个数取出每位数。我们利用数组来存储区间[0,N]的每一个数,数组的长度为N的位数 x (即最大位数) ,对于没有x位的数来说,我们在前位数面补0即可,这样我们只要扫描该最长数组,枚举数组每一位可能取的数(0,1,,,,9),就可以扫描区间[0,N]所有数字。
2,dp数组含义
dp[len][0] 表示前驱为非4,长度为len里面 “49” 数的个数。
dp[len][1] 表示前驱为4,长度为len里面 “49” 数的个数。
注意:
这些记录都是在没最大数限制的情况下记录的,所以在调用时必须不受大数限制(即前驱不是最大值)。这是因为我们每次输入的最大值是不同的,所以受最大值限制的数也会不同(即没有通用性),只要没受最大数限制的那些数对所有的N都可用(即具有通用性)。
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; typedef long long LL; LL dp[30][2]; //dp[len][0] 长度为len,且前驱不是4的个数 LL total[30]; int bit[30]; LL T,N; LL DFS(int Len,bool four,bool Max) {//长度,前驱是不是4, 前面是不是最大值 if(Len==0) return 0; if(!Max&&(dp[Len][four]!=-1)) return dp[Len][four];//不能是最大值时不受限制 LL res=0; int bian=9; if(Max)//len层循环的边界 bian=bit[Len]; for(int i=0;i<=bian ;i++) {//从0开始所以可以遍历所有0——N数 if(four&&i==9) {//出现49就剪枝 if(Max)//前驱全是最大值的情况 res+=(N%total[Len-1])+1; else res+=total[Len-1]; } else res+=DFS(Len-1,i==4,Max&&(i==bit[Len])); } if(!Max)//记录非最大值下一个N再用 dp[Len][four]=res; return res; } void solv(LL M) { int len=1; while(M) { bit[len++]=M%10; M=M/10; } bit[len]=0;//所以[0,N]的数第len为都为0 cout<<DFS(len-1,false,true)<<endl; } int main() { total[0]=1; for(int i=1;i<30;i++) total[i]=total[i-1]*10; memset(dp,-1,sizeof(dp)); scanf("%d",&T); while(T--) { scanf("%lld",&N); solv(N); } return 0; }
相关文章推荐
- Android(Java) 模拟登录知乎并抓取用户信息
- Eclipse去除js(JavaScript)验证错误介绍
- 代码静态检查-cppcheck
- 重写toString以及equals方法
- 【Java并发编程实战】-----“J.U.C”:锁,lock
- ORM框架基本认识
- Flask 安装 Ubuntu 14.04
- POJ 2594 Treasure Exploration(带交叉路的最小路径覆盖)
- HDU 1151 Air Raid(最小路径覆盖)
- java IO流(properties)
- HDOJ-2007-平方和与立方和
- 并查集 Ⅲ
- 前端框架技术
- Android项目目录结构介绍
- HDU 1054 Strategic Game
- POJ 3020 Antenna Placement
- 各种常用的JSON接口,开动你的大脑你就可以做出各种应用,值得收藏
- GR32 TImage32的图层绘制原理
- hdu 1241 AC广搜
- Ajax应用示例之用户名检查