数位dp基础(类似模板) HDU 2089+3555
来源:互联网 发布:博泰与创业软件 编辑:程序博客网 时间:2024/05/22 03:36
2089:求区间内不含62 和4的数字的个数
简单的数位dp,数位dp也就是搜索,按照位数来搜的,所以时间上应该是很快的,对于搜索,确定好当前所在长度(也就是搜到的当前数的长度),约束条件,还有是不是最后一个这个条件,
代码+解释
/* I believe xiaoxuzizhucan*/#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>using namespace std;#include<math.h>#include <queue>long long a[100];long long dp[200][5];//dfs(当前所在的位数,上一个数的i是不是等于6,是不是最后一位)long long dfs(long long pos,long long have,long long flag){ if(pos==0)//如果长度为0,也就是所搜到最后了,所以返回1,也就是这个数不含4和62,一位如果含有4和62,那就不会搜索到这一步,在下面的搜素过程中就continue了 { return 1; } if(flag==0&&dp[pos][have]!=-1)//同理,剪枝头,我不是很懂。。其实删去应该也是对的吧, { return dp[pos][have]; } long long sum=0; long long end=flag?a[pos]:9;//求该为所能搜索的最大值 for(long long i=0; i<=end; i++) { if(i==4||have&&i==2)//如果当前为为4,或者上一个状态为6并且这一个状态为2,也就是出现4或者出现62,那么就不要你继续往下搜索了。 continue; sum+=dfs(pos-1,i==6,flag&&i==end);//如果当前没有出现过4和62,然后就判断当前位是不是等于6, } if(flag==0)//入股不是最后一位,那么久赋值,方便上面剪枝使用 dp[pos][have]=sum; return sum;}long long solve(long long n){ long long len=1; while(n) { a[len++]=n%10; n/=10; } //printf("%d\n",len); return dfs(len-1,0,1);}int main(){ long long n,m; memset(dp,-1,sizeof(dp)); while(scanf("%I64d%I64d",&n,&m)!=EOF) { if(n==0&&m==0) break; printf("%I64d\n",solve(m)-solve(n-1)); }}
3555:
题意,让你找小于n的数中含有49的个数有多少。
同样也是很裸的数位dp,就不断地搜索就好了呗,想好状态变化就好了。
代码+解释
/* I believe xiaoxuzizhucan*/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<algorithm>using namespace std;#include<math.h>long long a[150];long long dp[150][5];//dfs(当前数的长度,上一位是不是6,是不是最后一位)long long dfs(long long pos,long long have ,long long flag){ if(pos==0)//长度为0如果have==2,也就是出现过49就返回1,表述出现了一个 { if(have==2) return 1; else return 0; } if(flag==0&&dp[pos][have]!=-1)//剪枝,也就是说如果当前位不是最后一位,并且被访问过,就直接返回 return dp[pos][have]; long long end=flag?a[pos]:9;//确定当前为最大值, long long sum=0; for(long long i=0; i<=end; i++) { long long temphave=have; if(have==1&&i!=4)//如果上一个是1,这一个不是1,那么就不可能有49 temphave=0; if(have==0&&i==4)//如果上一个不可能是49,但是这一个是4,那么标记为1,也就是表示上一个状态为4 temphave=1; if(have==1&&i==9)//如果上一个状态为4(have=1)并且这个状态为9,那么就出现49了,所以have==2代表49出现过 temphave=2; sum+=dfs(pos-1,temphave,flag&&i==end); } if(flag==0)//若果不是在最后一位 dp[pos][have]=sum; return sum;}long long suan(long long x){ long long len=1; while(x) { a[len++]=x%10; x/=10; } return dfs(len-1,0,1); }int main(){ long long test; memset(dp,-1,sizeof(dp)); scanf("%I64d",&test); while(test--) { long long n; scanf("%I64d",&n); printf("%I64d\n",suan(n)); }}
0 0
- 数位dp基础(类似模板) HDU 2089+3555
- hdu 2089(数位DP模板题)
- HDU 2089 不要62(类似hdu3555,数位dp)
- HDU 3555 Bomb(基础数位dp)
- hdu 2089 & hdu 3555 (数位DP)
- HDU 3555 D - Bomb(数位dp)(模板)
- HDU 3555 Bomb(数位DP模板啊两种形式)
- HDU 2089 不要62(数位DP入门+模板)
- hdu 3555 数位dp模板题
- 【HDU 3555】Bomb 数位dp模板
- hdu 2089 数位dp模板题
- hdu 3652 (数位dp 模板题)
- (hdu 2089 不要62)<基础数位DP>
- HDU 3555 Bomb 基础数位dp
- hdu 3555数位dp基础入门题
- hdu 2089 不要62 基础数位DP
- hdu 3555(数位dp)
- hdu 2089(数位DP)
- 【CodeChef-LYRC】Music & Lyrics【AC自动机】
- 微信飞机大战--基于cocos2d-x3.2
- -Os遇到的一个问题
- 56. Merge Intervals
- [HDU 5521] 2015ACM/ICPC亚洲区沈阳站 Meeting 最短路
- 数位dp基础(类似模板) HDU 2089+3555
- hdu 5492(矩阵模型的变形)
- LeetCode|Integer Break
- JavaScript中的变量
- LeetCode|Implement Queue using Stacks
- Outlook使用技巧
- Mini-Shell with pipeline
- 数码相框笔记
- Linux用户配置sudo权限(visudo)