【DP练习】Bomb(HDU3555)

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?
给一个数N,要求1到N中,数位中出现连续的49的数有多少个,比如49,149,249,499之类的。

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



代码

#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
long long m;
int b[50],dp[50][3],n;
int dfs(int x,int y,int flag)
{
	if(x==1) return 1;
	if(!flag&&dp[x][y]!=-1) return dp[x][y];
	int count=flag?b[x-1]:9,ans=0;
	for(int i=0;i<=count;++i)
	{
		if((y==1&&i==9)) continue;
		ans+=dfs(x-1,i==4?1:0,flag&&i==count);
	}
	return flag?ans:dp[x][y]=ans;
}
int start(long long x)
{
	int len=0;
	for(;x;x/=10) b[++len]=x%10;
	for(int i=0;i<=len+1;++i) dp[i][0]=dp[i][1]=-1;
	return dfs(len+1,0,1);
}
signed main()
{
	scanf("%lld",&n);
	for(int i=1;i<=n;++i) scanf("%lld",&m),printf("%lld
",m-start(m)+1);
	return 0;
}

另附思路2(大众):

  • dp[i][j]表示 当前为第 i 位,状态为j的在范围内,不是边界上,符合条件 数字的个数
  • j=1表示上一位出现4,j=2表示第1到i-1位出现49,否则为j=0。

核心代码:

LL dfs(int i,int j,int flag)
{
    if(i==1) return j==2;
    if(!flag && dp[i][j]!=-1) return dp[i][j];
    int bound=flag? lim[i-1]:9;
    LL ret=0;
    for(int k=0;k<=bound;k++)
    {
        if(j==2) ret+=dfs(i-1,2,flag&& k==bound);
        else if(k==9 && j==1) ret+=dfs(i-1,2,flag && k==bound);
        else if(k==4) ret+=dfs(i-1,1,flag && k==bound);
        else ret+=dfs(i-1,0,flag && k==bound);
    }
    return flag? ret:dp[i][j]=ret;
}
原文地址:https://www.cnblogs.com/wuwendongxi/p/13299364.html