HDU - 3555 Bomb(数位dp)
2016-07-20 17:09
330 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=3555题解:
开一个dp数组,i代表当前数字的长度,dp[i][0]表示不含49的数字个数,dp[i][1]表示最高位为9且不含49的数字的个数,dp[i][2]表示满足条件的数字个数。可以推出以下的递推公式:dp[0][0] = 1; for(int i = 1; i <= 22; i++) { dp[i][0] = dp[i-1][0] * 10 - dp[i-1][1];//不含49的数字个数 dp[i][1] = dp[i-1][0];//不含49 && 最高位为9的数字个数 dp[i][2] = dp[i-1][1] + dp[i-1][2] * 10;//满足条件的数字个数 }
然后讲数字按位输入到数组里,flag代表高位有没有出现过49。首先加上a[i] * i-1位中满足条件的数的个数,如果高位出现过49,加上a[i] * i-1位中不满足条件的数的个数,如果高位没有出现过49, 且第i位 > 4,则加上剩下i-1位中以9开头的数的个数。最后判断高一位和本位是否构成49,更新flag。
注意这种处理需要将n+1,因为处理的是【1, n)的情况,并且需要将最高位的高一位位数表示为0。
AC代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <sstream>
using namespace std;
long long int N;
int number[30];
long long int dp[25][3];
int main()
{
dp[0][0] = 1; for(int i = 1; i <= 22; i++) { dp[i][0] = dp[i-1][0] * 10 - dp[i-1][1];//不含49的数字个数 dp[i][1] = dp[i-1][0];//不含49 && 最高位为9的数字个数 dp[i][2] = dp[i-1][1] + dp[i-1][2] * 10;//满足条件的数字个数 }
int T;
scanf("%d", &T);
while(T--)
{
cin >> N;
N++;//将N加一
bool flag = false;
long long int ans = 0;
int len = 0;
memset(number,0,sizeof(number));
while(N != 0)
{
number[++ len ] = N%10;
N /= 10;
}
number[len + 1] = 0;//将高一位表示为0
for(int i = len; i > 0; i--)
{
ans += number[i] * dp[i-1][2];
if(flag)
ans += dp[i-1][0] * number[i];
if(number[i] > 4 && !flag)
ans += dp[i-1][1];
if(number[i+1] == 4 && number[i] == 9)
flag = true;
}
cout << ans <<endl;
}
return 0;
}
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACMer博客瀑布流分析
- ACM程序设计大赛题目分类
- 2015年acm国内排名
- 计算字符串最后一个单词长度
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1002