杭电3555

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就想学习一下
研究了很多天
感谢网上大神思路

题目大意 求出1---2^63-1中数字里含有49的数字的个数


#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#include<cstdlib>
#define mod 1000000007
using namespace std;
long long dp[21][3]={1};
long long pow(long long i){//求出10的i次方
    long long sum=1;
    while(i--)sum*=10;
    return sum;
}
int main(){
    for(int i=1;i<=20;i++){//
        dp[i][0]=dp[i-1][0]*10-dp[i-1][1];//到第i位不含49的数的个数 
        dp[i][1]=dp[i-1][0];//到第i位不含49但是位数是9的数的个数
        dp[i][2]=dp[i-1][2]*10+dp[i-1][1];//到第i位含49的数的个数
    }
    int t;
    cin>>t;
    while(t--){
        long long n,a[30],len=0;
        cin>>n;
        long long nn=n;
        while(n){
            a[++len]=n%10;
            n/=10;
        }
        long long k=len;
        long long sum=0,before=0;
        while(len){
            sum+=dp[len-1][2]*a[len];
            if(a[len]>4)
                sum+=dp[len-1][1];//这里好好理解
            if(a[len]==9&&before==4){
                sum+=(nn%pow(len-1));
                sum++;
                break;
            }
            before=a[len];
            len--;
        }
        cout<<sum<<endl;
    }
    return 0;
}


你可能感兴趣的:(杭电3555)