博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu2089 数位dp
阅读量:5252 次
发布时间:2019-06-14

本文共 2214 字,大约阅读时间需要 7 分钟。

数位dp第一题

题意:找从n到m中,不包含4,62(连续)的个数

先预处理出f数组     f[i][j]是以j开头的i位数不包含4,62的个数,可通过递推求解

递推关系式为:  f[i][j]=f[i-1][k]+f[i][j];对于第i位,可由第i-1位转移过来,用k枚举第i-1位的所有情况,j枚举第i位的所有情况,这时只需判断i和i-1位不为62,i位不为2的情况

用digit数组来记录从右到左的第i位,然后从最高位(最左边)开始枚举,从0枚举到digit【i】

例如432,这样便列举了所有情况

  4 3 2 4 3 2 4 3 2
枚举 0 枚举到3的取值 枚举到2的取值 4 0 枚举到2的取值 4 3 0
  1 枚举到3的取值 枚举到2的取值 4 1 枚举到2的取值 4 3 1
  2 枚举到3的取值 枚举到2的取值 4 2 枚举到2的取值      
  3 枚举到3的取值 枚举到2的取值            
                   
                   
                   
                   
                   

如果枚举完之后,保持最大值不变的情况下出现了4,62,则退出,如6231(枚举到3或1的情况时62会保持出现,这种情况要删去)

非递归版本的

#include
#define C 0.5772156649#define pi acos(-1.0)#define ll long long#define mod 1000000007#define ls l,m,rt<<1#define rs m+1,r,rt<<1|1#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const double g=10.0,eps=1e-7;const int N=10+10,maxn=1000000+10,inf=0x3f3f3f;int f[N][N];//f[i][j]以j开头的i位数不包含4,62的个数int digit[10];//从右到左第i位是多少int getnum(int x){ int len=0,ans=0; memset(digit,0,sizeof digit); while(x) { digit[++len]=x%10; x/=10; } for(int i=len; i>=1; i--) { for(int j=0; j
>n>>m) { if(!n&&!m)break; cout<
<
View Code

 递归版本的

#include
#define C 0.5772156649#define pi acos(-1.0)#define ll long long#define mod 1000000007#define ls l,m,rt<<1#define rs m+1,r,rt<<1|1#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const double g=10.0,eps=1e-7;const int N=20+10,maxn=1000000+10,inf=0x3f3f3f;int dp[N][N],digit[N];int dfs(int len,bool state,bool fp)//state-当前是不是等于6,fp是否访问过{ if(!len)return 1; if(!fp&&dp[len][state]!=-1)return dp[len][state]; int ret=0,fpmax=fp ? digit[len] : 9; for(int i=0;i<=fpmax;i++) { if(i==4||state&&i==2)continue; ret+=dfs(len-1,i==6,fp&&i==fpmax); } if(!fp)dp[len][state]=ret; return ret;}int solve(int x){ int len=0; while(x) { digit[++len]=x%10; x/=10; } return dfs(len,0,1);}int main(){ ios::sync_with_stdio(false); cin.tie(0); int a,b; memset(dp,-1,sizeof dp); while(cin>>a>>b) { if(a==0&&b==0)break; cout<
<
View Code

发现网上的代码关于数位dp的几乎都是递归写的,所以还是找递归版本理解比较好

转载于:https://www.cnblogs.com/acjiumeng/p/7416986.html

你可能感兴趣的文章
【hdu 1429】胜利大逃亡(续)
查看>>
图论-次短路求法
查看>>
What's New for Visual C# 6.0
查看>>
ExtJs学习笔记之ComboBox组件
查看>>
关于收费软件
查看>>
getopt_long
查看>>
TensorFlow MNIST CNN 代码
查看>>
javascript之Style物
查看>>
图的深度优先遍历
查看>>
C# 之 提高WebService性能大数据量网络传输处理
查看>>
[bzoj1004] [HNOI2008] Cards
查看>>
原生HttpClient详细使用示例
查看>>
几道面试题
查看>>
Factory Design Pattern
查看>>
python中贪婪与非贪婪
查看>>
guava API整理
查看>>
无锁编程笔记
查看>>
jquery mobile
查看>>
如何在vue单页应用中使用百度地图
查看>>
Springboot使用步骤
查看>>