您的位置:首页 > 其它

HDU3555 Bomb —— 数位DP

2017-07-23 00:08 411 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555


Bomb

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)

Total Submission(s): 18739    Accepted Submission(s): 6929


Problem Description

The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49", the power of the blast would
add one point.

Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?

 

Input

The first line of input consists of an integer T (1 <= T <= 10000), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description.

The input terminates by end of file marker.

 

Output

For each test case, output an integer indicating the final points of the power.

 

Sample Input

3
1
50
500

 

Sample Output

0
1
15

HintFrom 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通用:dp[pos][sta1][sta2][……]

表示:当前位为pos,之前的状态为sta1*sta2*……stan。n为限制条件的个数。

回到此题,限制条件有两个: 1.上一位是否为4; 2.之前是否已经出现49。

类似题目:http://blog.csdn.net/dolfamingo/article/details/72848001

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
//#define LOCAL
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+7;
const int maxn = 100+10;

LL n;
LL a[maxn], dp[maxn][2][2];

LL dfs(int pos, bool is4, bool lim, bool hav)
{
if(!pos) return hav;
if(!lim && dp[pos][is4][hav]!=-1) return dp[pos][is4][hav];

LL ret = 0;
int m = lim?a[pos]:9;
for(int i = 0; i<=m; i++)
{
bool B = is4&&(i==9);
ret += dfs(pos-1, i==4, lim&&(i==m), B||hav);
}

if(!lim) dp[pos][is4][hav] = ret;
return ret;
}

int main()
{
#ifdef LOCAL
freopen("123", "r", stdin);
//      freopen("output.txt", "w", stdout);
#endif

int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
int p = 0;
while(n)
{
a[++p] = n%10;
n /= 10;
}
ms(dp,-1);
LL ans = dfs(p, 0, 1, 0);
printf("%lld\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: