[动态规划][数位dp]Bomb

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
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--记忆化搜索
AC代码:
#include <iostream>
#include<cstdio>
typedef long long ll;
using namespace std;

ll dp[15][2];
ll digit[15];

ll dfs(ll len,bool last_4,bool limit){
  if(len==0) return 1;
  if(!limit && dp[len][last_4]) return dp[len][last_4];
  ll sum=0;
  for(ll i=0;i<=(limit?digit[len]:9);i++){
    if(!(last_4&&i==9)) sum+=dfs(len-1,i==4,limit&&i==digit[len]);
  }
  if(!limit) dp[len][last_4]=sum;
  return sum;
}

ll solve(ll x){
  digit[0]=0;
  while(x){
    digit[++digit[0]]=x%10;
    x/=10;
  }
  return dfs(digit[0],false,true);
}

int main()
{
    ll t;scanf("%lld",&t);
    while(t--){
        ll n;scanf("%lld",&n);
        printf("%lld\n",n-(solve(n)-1));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lllxq/p/9428677.html