您的位置:首页 > 其它

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:

//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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: