数位dp的简单使用
来源:互联网 发布:sql limit 编辑:程序博客网 时间:2024/05/06 02:04
题目:给出不多1000位的数,每一位由0、1、2、3组成。
条件:所有的0都在1之前,所有的2都在3之前,0不能在首位,另外0、1、2、3必须出现至少一次。由于数较大所以结果对1000000007取余。
问题:求满足条件的数的数量。
条件:所有的0都在1之前,所有的2都在3之前,0不能在首位,另外0、1、2、3必须出现至少一次。由于数较大所以结果对1000000007取余。
问题:求满足条件的数的数量。
分析:明显这类题目是无法通过暴力遍历解决的。所以需要通过数位dp解决。
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int dp[1005][2][2][2][2],digit[1005];void init(){ memset(dp,-1,sizeof(dp)); //初始化dp数组}int dfs(int len,int i,int j,int k,int l,int flag) //len表示当前位,i,j,k,l分别表示是否包含0、1、2、3(0表示不包含,1表示包含),flag表示是否达到上限(1为达到,0为未达到){ if(len<=0) return (i&&j&&k&&l); if(!flag&&dp[len][i][j][k][l]!=-1) return dp[len][i][j][k][l]; int n=flag?digit[len]:3; int ans=0; for(int i1=0;i1<=n;i1++) { int i2=i,j1=j,k1=k,l1=l; if(j==0&&k==0&&l==0&&i1==0) continue; if(i1==0&&j==1) continue; else if(i1==0&&j==0) i2=1; else if(i1==1&&i==0) continue; else if(i==1&&i1==1) j1=1; else if(i1==2&&l==1) continue; else if(i1==2&&l==0) k1=1; else if(i1==3&&k==0) continue; else if(i1==3&&k==1) l1=1; ans=(ans+dfs(len-1,i2,j1,k1,l1,flag&&i1==n))%1000000007; } if(!flag) dp[len][i][j][k][l]=ans; return ans;}int main(){ int n,summ; scanf("%d",&n); init(); digit[n]=2; for(int i=n-1;i>0;i--) digit[i]=3; summ=dfs(n,0,0,0,0,1); printf("%d\n",summ); return 0;}另外,数位dp上面这种实现方式必须dfs函数的for循环对于i,j,k,l形参的操作必须重新定义变量,而不能直接使用原变量,因为这可能导致for循环的下一个循环的变量i,j,k,l改变。
1 0
- 数位dp的简单使用
- 简单的数位dp
- 简单的数位dp练习
- BNU1065:简单的问题(数位dp)
- HDU2089 不要62(简单的数位DP)
- 简单数位dp,uestc1307
- 简单数位DP
- 简单数位dp
- 简单数位DP
- 简单数位DP总结
- 简单的数位dp是怎样运行的
- hdu4722之简单数位dp
- 数位dp简单题目汇总
- hdu2089||hdu3555简单数位DP
- 艰难的数位DP
- 某大牛的数位DP
- 简单数位dp-hdu-4734-F(x)
- HDU 2089 数位dp (简单)
- CodeForces 746B Decoding
- android fragment
- Windows下定长数据接收源码
- 14. Longest Common Prefix
- 51Nod - 1091 模拟
- 数位dp的简单使用
- //1.编写代码模拟三次密码输入的场景。//2.编写一个程序,可以一直接收键盘字符,如果是小写字符就输出对应的大写字符,如果接收的是大写字符,就输出对应的小写字符,如果是数字不输出。
- java线程
- SQL SERVER 触发器 inserted和deleted表
- HDFS High Availability
- PHP开发规范
- LeetCode 473. Matchsticks to Square
- 【UML】交互图之序列图、协作图
- jsp:include标签参数传递及捕获