您的位置:首页 > 其它

HDU 3555 Bomb (数位DP)

2013-09-02 21:37 441 查看
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3555

题目大意:从0开始到给定的数字N所有的数字中遇到“49”的数字的个数。

[align=left]Sample Input[/align]

3
1
50
500

[align=left]Sample Output[/align]

0
1
15

Hint
From 1 to 500, the numbers that include the sub-sequence "49" are "49","149","249","349","449","490","491","492","493","494","495","496","497","498","499", so the answer is 15.

分析:定义dp[25][3]

dp[len][0] 表示前len位没有49的数字的个数
dp[len][1] 表示前len位没有49但是以9结尾的数的个数
dp[len][2] 表示前len位有49的状态

代码如下:

# include<stdio.h>
# include<string.h>
__int64 dp[25][3],N;
int digit[25];
void init(){
memset(dp,0,sizeof(dp));
dp[0][0] = 1;
for(int i =1; i<=20; i++){
dp[i][0] = dp[i-1][0]*10 - dp[i-1][1];
//①:dp[i-1][0]*10代表当前可选择0-9十个数 ②:dp[i-1][1]当前以9开头的数的个数。
//③dp[i-1][0]*10-dp[i-1][1]代表不包含49的个数。
dp[i][1] = dp[i-1][0];
//①dp[i-1][0]代表以9开头的个数的数目
dp[i][2] = dp[i-1][2]*10 + dp[i-1][1];
//以49开头的个数(分为两种情况:①dp[i][2]:x49xxx  ②当第一个x为4时满足条件dp[i][1]x9xxxx
}
}
int main(){
init();
int T,len,flag,i;
__int64 ans;
scanf("%d",&T);
while(T--){
flag = ans = 0;
scanf("%I64d",&N);
N++;
memset(digit,0,sizeof(digit));
len = 1;
while(N){    //逆序存放
digit[len++] = N%10;
N /= 10;
}
for(i=len-1; i>0; i--){
ans += digit[i] * dp[i-1][2];    //开头为x49的个数
if(flag)
ans += digit[i]*dp[i-1][0];    //开头为49的个数
else if(!flag && digit[i]>4)
ans += dp[i-1][1];    //开头我x9(x>4)的个数
if(digit[i+1]==4 && digit[i]==9)
flag = 1;
}
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: