HDU 3555 水数位dp
来源:互联网 发布:cnnic数据报告 2017 编辑:程序博客网 时间:2024/04/29 07:46
和 hdu 2089 一样的思路,这个是找数字中带有 49 的,我dp的不带 49 的 一减就可以了。
dp 出来的个数是从0 开始的。
当然。。。后来。。。就是现在。。我又写了另一个版本。。。找数字中带有 49 的。代码在下面。。
#include <stdio.h>#include <iostream>#include <queue>#include <algorithm>#include <map>#include <vector>#include <cmath>#include <string.h>#include <stdlib.h>#include <time.h>#include <fstream>#include <set>#include <stack>using namespace std;#define READ freopen("acm.in","r",stdin)#define WRITE freopen("acm.out","w",stdout)#define ll long long#define ull unsigned long long #define PII pair<int,int>#define PDI pair<double,int>#define PDD pair<double,double>#define MII map<int,int>::iterator #define fst first#define sec second#define MS(x,d) memset(x,d,sizeof(x))#define INF 0x3f3f3f3f#define ALL(x) x.begin(),x.end()#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define ROOT 0,n-1,1#define PB push_back#define FOR(a,b,c) for(int a=b;a<c;a++)#define MOD 10007#define keyTree (ch[ ch[root][1] ][0])#define MAX 111ll dp[MAX][MAX];int digit[MAX];int len;ll dfs(int i,int s,bool e){ if(i==0) return s==0; if(!e&&dp[i][s]!=-1) return dp[i][s]; int u=e?digit[i-1]:9; ll res=0; for(int j=0;j<=u;j++) { if(!(s==4&&j==9)) res+=dfs(i-1,j,e&&j==u); } return e?res:dp[i][s]=res;}ll cal(ll n){ MS(digit,0); len=0; while(n) { digit[++len]=n%10; n/=10; } return dfs(len+1,0,1);}int main(){ MS(dp,-1); int cas; scanf("%d",&cas); while(cas--) { ll t; cin>>t; cout<<t+1-cal(t)<<endl; } return 0;}
其实写完不要62就觉得挺奇怪的。。为毛我觉得写不要62和要62感觉差距好多。。
后来想了。。。很久。。原来是状态不够细啊。。。
dp[i][j][flag] 表示长度为 i 的开头为 j 的数字中 带49的有几个。。不带49 的有几个,这样状态描述才完整
否则的话。。转移的时候很难搞。。。到底该咋转移才能不重复呢。。比如说。。s=4,j=9 的时候,如果直接加的话。。会有漏算的,因为后面不带49的现在也带49了,不直接加的话。。又会少。。所以,dp 中状态描述完整是最重要和最前面的一步。
#include <stdio.h>#include <iostream>#include <queue>#include <algorithm>#include <map>#include <vector>#include <cmath>#include <string.h>#include <stdlib.h>#include <time.h>#include <fstream>#include <set>#include <stack>using namespace std;#define READ freopen("acm.in","r",stdin)#define WRITE freopen("acm.out","w",stdout)#define ll long long#define ull unsigned long long #define PII pair<int,int>#define PDI pair<double,int>#define PDD pair<double,double>#define MII map<int,int>::iterator #define fst first#define sec second#define MS(x,d) memset(x,d,sizeof(x))#define INF 0x3f3f3f3f#define ALL(x) x.begin(),x.end()#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define ROOT 0,n-1,1#define PB push_back#define FOR(a,b,c) for(int a=b;a<c;a++)#define MOD 10007#define keyTree (ch[ ch[root][1] ][0])#define MAX 111ll dp[MAX][MAX][3];int digit[MAX];int len;ll fac[100];ll dfs(int i,int s,int flag,bool e){ if(i==1&&flag) return 0; if(i==1&&!flag) return 1; if(!e&&dp[i][s][flag]!=-1) return dp[i][s][flag]; int u=e?digit[i-1]:9; ll res=0; for(int j=0;j<=u;j++) { if(!flag&&s==4&&j==9) continue; res+=dfs(i-1,j,flag,e&&j==u); if(flag&&s==4&&j==9) res+=dfs(i-1,j,0,e&&j==u); } return e?res:dp[i][s][flag]=res;}ll cal(ll n){ MS(digit,0); len=0; while(n) { digit[++len]=n%10; n/=10; } return dfs(len+1,0,1,1);}int main(){ MS(dp,-1); int cas; scanf("%d",&cas); fac[0]=1; for(int i=1;i<20;i++) fac[i]=10*fac[i-1]; while(cas--) { ll t; cin>>t; cout<<cal(t)<<endl; } return 0;}
0 0
- HDU 3555 水数位dp
- hdu 3555 数位dp
- hdu 3555 数位dp
- HDU 3555 数位DP
- HDU 3555 \数位DP
- hdu 3555 数位DP
- HDU 3555 数位DP
- hdu 3555 数位DP
- hdu 3555 数位dp
- 数位DP HDU-3555
- HDU 3555 数位DP
- hdu 3555(数位dp)
- hdu 3555(数位dp)
- hdu 3555(数位dp)
- HDU 3555 数位DP
- hdu 3555【数位DP】
- hdu 3555(数位dp)
- HDU 3555 数位DP
- TestMulTable.java
- 第四周项目2-三角形类2
- 【Android】The application has stopped unexpectedly.Please try again.
- 第二周实验作业之一(修改版)
- 【苹果鼠标滑轮失灵】解决办法
- HDU 3555 水数位dp
- 如何防止sql注入
- 第二周实验作业之二
- 数据库中事务DML,DDL,DCL,数据字典概念
- 折半插入排序
- OpenStack Swift源码分析(二)ring文件的生成
- [cocos2d-x菜鸟学习记录]从构建环境到项目创建
- Single Number I & II
- LeetCode Search in Rotated Sorted Array