hdu 3555 Bomb 数位dp

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL __int64
LL dp[22][3];
int main()
{
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;
    for(LL 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位数中,开头为9,且不含49的数
        dp[i][2]=dp[i-1][2]*10+dp[i-1][1];
        //cout<<dp[i][0]<<" "<<dp[i][1]<<" "<<dp[i][2]<<endl;
    }
    LL T;
    cin>>T;
    while(T--)
    {
        LL n,m=0,s[22],i;
        cin>>n;
        //n=(LL)pow(2,63)-1;
        //n++;
        while(n)
        {
            s[++m]=n%10;
            n=n/10;
        }
        LL ans=0,flag=0,last=-1;//last记得赋值,不然就OVER了
        for(i=m;i>=1;i--)
        {
            ans+=dp[i-1][2]*s[i];
            if(flag)
            {
                ans+=dp[i-1][0]*s[i];
            }
            if(!flag&&s[i]>4)
            {
                ans+=dp[i-1][1];
            }
            if(last==4&&s[i]==9)
            {
                flag=1;
            }
            last=s[i];
        }
        if(flag)
            ans++;
        cout<<ans<<endl;
    }
    return 0;
}
/*
    对于5673,
    处理顺序是0~4999,5000~5599,5600~5669,5670~5672,5673
*/

你可能感兴趣的:(数位dp)