HDU POJ 数位DP
来源:互联网 发布:权力的游戏山姆知乎 编辑:程序博客网 时间:2024/05/19 23:15
预处理求出所有答案,再根据具体数字求解,模板性较强。
DP版要想方程,所以还是记忆化搜索版容易,就是枚举每一位。
看http://blog.csdn.net/synapse7/article/details/21006265?utm_source=tuicoo的注释大概能懂。
递归版利用了bit从1计数,而参数按0计数。如
23则bit[1]=3,bit[2]=2,传len=2进去,然后for遍历bit[2]顺便把len-1递归下去,然后len=1时遍历bit[1]=3,继续传0进去,然后返回
HDU 3555 BOMB 不含49
#include <cstdio>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define CLR( a , x ) memset ( a , x , sizeof (a) )#define RE freopen("1.in","r",stdin)ll dp[25][3]; //dp[i][j]:i长度j情况//dp[i][0] 长度为i且不含49//dp[i][1] 长度为i不含49但以9开头//dp[i][2] 长度为i含49int bit[25];void init(){ CLR(dp,0); dp[0][0] = 1; for(int i=1;i<=20;i++) //2^63次方在20位以内 { dp[i][0] = dp[i-1][0]*10-dp[i-1][1]; //不含49*10-补上4组成的49 dp[i][1] = dp[i-1][0]; //补上9 dp[i][2] = dp[i-1][2]*10+dp[i-1][1]; //已含49*10+补上4组成的49 }}int main(){ //RE; int t; ll n; init(); cin>>t; while(t--) { cin>>n; n++; int len = 0; ll ans = 0; while(n) { bit[++len] = n % 10; n /= 10; } bit[len+1] = 0; bool flag = false; for(int i=len;i>=0;i--) { ans += dp[i-1][2]*bit[i]; //低位含49的*该位数字 if(flag) ans += dp[i-1][0]*bit[i]; //组成49后就+=低位*该位 if(!flag && bit[i]>4) //后一位是9,那么数字大于4的都包含49 ans += dp[i-1][1]; if(bit[i]==9 && bit[i+1]==4) //组成49 flag = true; } cout<<ans<<endl; }}
递归版
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <set>#include <map>#include <stack>#include <queue>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define eps 10^(-6)#define Q_CIN ios::sync_with_stdio(false);#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("1.out","w",stdout);#define MOD 10009#define bug(x) cout<<#x<<":"<<(x)<<endl;#define sf(a) scanf("%d",&a)#define sff(a,b) scanf("%d%d",&a,&b) #define sfff(a,b,c) scanf("%d%d%d",&a,&b,&c) #define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=25;const int maxm=1e6+5;const int inf = 0x3f3f3f3f;int bit[maxn];ll dp[maxn][2][2];ll dfs(int len,bool is4,bool ok49,bool ismax){ if(len<=0) return ok49?1:0; if(!ismax && dp[len][is4][ok49] != -1) return dp[len][is4][ok49]; int pmax = ismax ? bit[len] : 9; ll cnt = 0; for (int i = 0; i <= pmax; ++i){ cnt += dfs(len - 1,i == 4,ok49 || (is4 && i == 9),ismax && i == pmax); } return ismax ? cnt : dp[len][is4][ok49] = cnt;}ll solve(ll n){ int cnt=0; while(n){ bit[++cnt]=n%10; n/=10; } return dfs(cnt,false,false,true);}int main(){ #ifndef ONLINE_JUDGE freopen("1.in","r",stdin); #endif ll a,t; memset(dp,-1,sizeof(dp)); cin>>t; while(t--){ cin>>a; cout<<solve(a)<<endl; } return 0;}
HDU 2089 不要62 不含4和相邻62的数
#include <cstdio>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define Q_CIN ios::sync_with_stdio(false)#define CLR( a , x ) memset ( a , x , sizeof (a) )#define RE freopen("1.in","r",stdin)int dp[10][3];//dp[i][0] 长度为i,无不吉利且不以2开头//dp[i][1] 长度为i,无但以2开头//dp[i][2] 长度为i,有int bit[10];void init(){ CLR(dp,0); dp[0][0] = 1; for(int i=1;i<=10;i++) { dp[i][0] = dp[i-1][0]*9-dp[i-1][1]; //除4外的9个-后一位是2的情况 dp[i][1] = dp[i-1][0]; //直接加2 dp[i][2] = dp[i-1][2]*10+dp[i-1][1]+dp[i-1][0]; //原有的+加6的+加4的 }}int solve(int n){ int len = 0; int ans = 0; int tmp = n; while(n) { bit[++len] = n % 10; n /= 10; } bit[len+1] = 0; bool flag = false; for(int i=len;i>=0;i--) { ans += dp[i-1][2]*bit[i]; if(flag) ans += dp[i-1][0]*bit[i]; if(!flag && bit[i]>6) ans += dp[i-1][1]; if(!flag && bit[i]>2&&bit[i+1]==6)//62x ans += dp[i][1]; //dp[i][1] if(!flag && bit[i]>4) ans += dp[i-1][0]; if((bit[i]==2 && bit[i+1]==6)||bit[i]==4) flag = true; } return tmp-ans; //求没有不吉利的}int main(){// RE; int n,m; init(); while(cin>>n>>m,m||n) { CLR(bit,0); cout<<solve(m+1)-solve(n)<<endl; //[n,m]=[1,m]-[1,n) } return 0;}
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <set>#include <map>#include <stack>#include <queue>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define eps 10^(-6)#define Q_CIN ios::sync_with_stdio(false);#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("1.out","w",stdout);#define MOD 10009#define bug(x) cout<<#x<<":"<<(x)<<endl;#define sf(a) scanf("%d",&a)#define sff(a,b) scanf("%d%d",&a,&b) #define sfff(a,b,c) scanf("%d%d%d",&a,&b,&c) #define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=10;const int maxm=1e6+5;const int inf = 0x3f3f3f3f;int bit[maxn];int dp[maxn][2];int dfs(int len,bool is6,bool ismax){ if(len==0) return 1; if(!ismax&&dp[len][is6]>=0) return dp[len][is6]; int cnt=0,pmax=(ismax?bit[len]:9); for (int i = 0; i <= pmax; ++i){ if(i==4||(is6&&i==2)) continue; cnt+=dfs(len-1,i==6,ismax&&i==pmax); } return ismax?cnt:dp[len][is6]=cnt;}int solve(int n){ int cnt=0; while(n){ bit[++cnt]=n%10; n/=10; } return dfs(cnt,false,true);}int main(){ #ifndef ONLINE_JUDGE freopen("1.in","r",stdin); #endif int a,b; memset(dp,-1,sizeof(dp)); while(cin>>a>>b,a||b){ cout<<solve(b)-solve(a-1)<<endl; } return 0;}
POJ 3252 Round Numbers
求[x,y]区间内“二进制表示0比1多的数”的个数。处理前导0,前导0不算0。
dp[len][num0][num1]:长度为len,0的数量为num0,1数量为num1的个数
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=50;const int maxm=1e6+5;const int inf = 0x3f3f3f3f;int bit[maxn];int dp[maxn][maxn][maxn];int dfs(int len,int num0,int num1,bool first,bool ismax){ if(len==0) return num0>=num1?1:0; if(!ismax && dp[len][num0][num1] != -1) return dp[len][num0][num1]; int pmax = ismax ? bit[len] : 1; int cnt = 0; for (int i = 0; i <= pmax; ++i){ if(first){ if(i==0) cnt += dfs(len-1,0,0,true,ismax&&i==pmax); else cnt += dfs(len-1,0,1,false,ismax&&i==pmax); }else{ if(i==0) cnt += dfs(len-1,num0+1,num1,false,ismax&&i==pmax); else cnt += dfs(len-1,num0,num1+1,false,ismax&&i==pmax); } } return ismax ? cnt : dp[len][num0][num1] = cnt;}int solve(int n){ int cnt=0; while(n){ bit[++cnt]=n%2; n/=2; } return dfs(cnt,0,0,true,true);}int main(){ #ifndef ONLINE_JUDGE freopen("1.in","r",stdin); #endif int a,t,b; memset(dp,-1,sizeof(dp)); while(cin>>a>>b) cout<<solve(b)-solve(a-1)<<endl; return 0;}
弱校OJ 233数
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <map>#include <queue>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("1.out","w",stdout);#define MOD 10009#define bug(x) cout<<#x<<":"<<(x)<<endl;#define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=50;const int maxm=1e6+5;const int inf = 0x3f3f3f3f;int bit[maxn];ll dp[maxn][2][2][2]; //长度,是不是1,是不是23,是不是233ll dfs(int len,bool is2,bool is23,bool ok,bool ismax){ if(len<=0) return ok?1:0; if(!ismax && (dp[len][is2][is23][ok] != -1)) return dp[len][is2][is23][ok]; int pmax = ismax ? bit[len] : 9; ll cnt = 0; for (int i = 0; i <= pmax; ++i){ cnt += dfs(len - 1,i==2,is2&&i == 3,ok||(is23&&i==3),ismax && i == pmax); } return ismax ? cnt : dp[len][is2][is23][ok] = cnt;}ll solve(ll n){ int cnt=0; while(n>0){ bit[++cnt]=n%10; n/=10; } return dfs(cnt,false,false,false,true);}int main(){ // #ifndef ONLINE_JUDGE // freopen("1.in","r",stdin); // freopen("1.out","w",stdout); // #endif ll a,t; memset(dp,-1,sizeof(dp)); cin>>t; while(t--){ cin>>a; cout<<solve(a)<<endl; } return 0;}
HDU 3652 B-number
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <set>#include <map>#include <stack>#include <queue>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define eps 10^(-6)#define Q_CIN ios::sync_with_stdio(false);#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("1.out","w",stdout);#define MOD 10009#define bug(x) cout<<#x<<":"<<(x)<<endl;#define sf(a) scanf("%d",&a)#define sff(a,b) scanf("%d%d",&a,&b) #define sfff(a,b,c) scanf("%d%d%d",&a,&b,&c) #define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=20;const int maxm=1e6+5;const int inf = 0x3f3f3f3f;int bit[maxn];ll dp[maxn][2][2][13]; //dp[i][j][k][k]:长度为i,是否以1结尾,有无13,模13的结果ll dfs(int len,bool end1,bool have13,int mod,bool ismax){ if(len==0) return (!mod && have13); if(!ismax && (dp[len][end1][have13][mod] != -1)) return dp[len][end1][have13][mod]; int pmax = ismax ? bit[len] : 9; ll cnt = 0; for (int i = 0; i <= pmax; ++i){ int tmod = (mod*10+i) % 13; cnt += dfs(len-1,i==1,have13||(end1&&i==3),tmod,ismax && i == pmax); } return ismax ? cnt : dp[len][end1][have13][mod] = cnt;}ll solve(ll n){ int cnt=0; while(n>0){ bit[++cnt]=n%10; n/=10; } return dfs(cnt,false,false,0,true);}int main(){ ll a,t; memset(dp,-1,sizeof(dp)); while(cin>>a){ cout<<solve(a)<<endl; } return 0;}
0 0
- HDU POJ 数位DP
- poj 3286-数位DP
- poj 2282-数位DP
- poj 3286 数位dp
- POJ 3252 数位DP
- poj 2282 数位dp
- poj 3252 数位DP
- poj 1850 数位DP
- POJ 3252 数位dp
- poj 3252 数位DP
- poj 2089 数位DP
- POJ 2282 数位dp
- POJ 3252 数位DP
- POJ - 3252 数位dp
- POJ-3252-数位dp
- POJ 3252 数位DP
- hdu 3555 数位dp
- hdu 3555 数位dp
- 实现textarea限制输入字数
- java中的用户名和密码加密保存到txt文件中
- gitHub无法访问问题
- 关于:清除并发请求和(或)管理器数据 请求的理解
- IOS获取文件/文件夹大小
- HDU POJ 数位DP
- Bash引号的那点事
- iOS中使用block进行网络请求回调 - xuym
- 自定义拷贝粘贴窗口
- C语言文件操作之EOF解析
- Actionbar 解决溢出菜单不显示的问题
- 网易微博将正式关闭 用户迁至轻博客LOFTER
- Digester解析xml文件
- ios7返回手势优化