HDU-3555 Bomb 数位DP
2013-03-21 14:35
423 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555
我的DP方程:f[i][j]表示数的第i位以j开头的数含有49的个数,则状态转移方程为:
1.j!=4时: f[i][j]=sum{ f[i-1][k] | 0<=k<=9 }
2.j==4时:f[i][j]=sum{ f[i-1][k] | 0<=k<=9 } - f[i-1][9] + pow(10,i-2) (因为j=4时,只要i-1位为9,后面的都满足)
这样的转移方程思路比较清晰,在网上看到别人的转移方程是这样的:
1.f[i][0]=10*f[i-1][0]-f[i-1][1]; 表示不含49的个数
2.f[i][1]=f[i-1][0]; 表示以9开头不含49的个数
3.f[i][2]=10*f[i-1][2]+f[i-1][1]; 表示含49的个数
的确比我的优化些,把其它不需要的状态放在一起了。
DP1:
DP2:
我的DP方程:f[i][j]表示数的第i位以j开头的数含有49的个数,则状态转移方程为:
1.j!=4时: f[i][j]=sum{ f[i-1][k] | 0<=k<=9 }
2.j==4时:f[i][j]=sum{ f[i-1][k] | 0<=k<=9 } - f[i-1][9] + pow(10,i-2) (因为j=4时,只要i-1位为9,后面的都满足)
这样的转移方程思路比较清晰,在网上看到别人的转移方程是这样的:
1.f[i][0]=10*f[i-1][0]-f[i-1][1]; 表示不含49的个数
2.f[i][1]=f[i-1][0]; 表示以9开头不含49的个数
3.f[i][2]=10*f[i-1][2]+f[i-1][1]; 表示含49的个数
的确比我的优化些,把其它不需要的状态放在一起了。
DP1:
//STATUS:C++_AC_15MS_288KB #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<iostream> #include<string> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> using namespace std; #define LL __int64 #define pii pair<int,int> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 const int N=65,INF=0x3f3f3f3f,MOD=100000000; //const double DNF=100000000000; LL f [11],d ; int T; LL n; int main() { // freopen("in.txt","r",stdin); int i,j,len,num ,k,la; LL t,ans; d[0]=1; for(i=1;i<20;i++)d[i]=d[i-1]*10; f[1][4]=1; for(i=2;i<20;i++){ for(j=0;j<10;j++){ for(k=0;k<10;k++)f[i][j]+=f[i-1][k]; if(j==4){ f[i][j]-=f[i-1][9]; f[i][j]+=d[i-1]; } } } scanf("%d",&T); while(T--) { scanf("%I64d",&n); len=0;ans=0; do num[len++]=n%10; while(n/=10); for(i=len-1,la=-1;i>=0;la=num[i--]){ for(j=num[i]-1;j>=0;j--) ans+=f[i][j]; if(num[i]==9 && la==4){ for(t=1,i--;i>=0;i--) t+=num[i]*d[i]; ans+=t; } } printf("%I64d\n",ans); } return 0; }
DP2:
//STATUS:C++_AC_15MS_264KB #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<iostream> #include<string> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> using namespace std; #define LL __int64 #define pii pair<int,int> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 const int N=65,INF=0x3f3f3f3f,MOD=100000000; //const double DNF=100000000000; LL f [4],d ; int T; LL n; int main() { // freopen("in.txt","r",stdin); int i,j,len,num ,k,la; LL t,ans; d[0]=1; for(i=1;i<20;i++)d[i]=d[i-1]*10; f[0][0]=10;f[0][1]=1;f[0][2]=0; for(i=1;i<20;i++){ f[i][0]=10*f[i-1][0]-f[i-1][1]; f[i][1]=f[i-1][0]; f[i][2]=10*f[i-1][2]+f[i-1][1]; } scanf("%d",&T); while(T--) { scanf("%I64d",&n); len=0;ans=0; do num[len++]=n%10; while(n/=10); for(i=len-1,la=-1;i>=0;la=num[i--]){ if(i>0){ ans+=num[i]*f[i-1][2]; if(num[i]>4)ans+=f[i-1][1]; } if(num[i]==9 && la==4){ for(t=1,i--;i>=0;i--) t+=num[i]*d[i]; ans+=t; } } printf("%I64d\n",ans); } return 0; }
相关文章推荐
- HDU-3555 Bomb 数位DP
- HDU --3555--Bomb--数位DP
- HDU 3555 Bomb 数位DP 入门
- HDU 3555 Bomb(基础数位dp)
- HDU 3555 Bomb (数位DP)
- hdu 3555 Bomb 【数位DP】
- hdu 3555 Bomb (数位DP)
- [数位DP]Hdu 3555——Bomb
- HDU 3555 Bomb(数位DP)
- HDU 3555 Bomb(数位DP)
- hdu 3555 Bomb【数位dp~吖!!!!!】
- 【HDU 3555】Bomb 数位dp模板
- HDU-3555-Bomb(数位DP)
- hdu 3555 Bomb(数位dp)
- HDU - 3555 Bomb(数位dp)
- [HDU 3555]Bomb[数位DP]
- Bomb(HDU 3555 数位DP)
- Bomb - HDU 3555 数位dp
- HDU 3555 Bomb + HDU 2089 不要62 数位dp入门题目
- [数位DP] HDU 3555 Bomb