数位DP HDU-3555

来源:互联网 发布:java时间序列预测算法 编辑:程序博客网 时间:2024/05/07 01:28

题目大意:计算0~n内含有“49”子串的数字的个数

数位dp[i][j]: i:长度     j:不含49/首字符为9 但不含49/含49

dp[i][0]=10*dp[i-1][0]-dp[i-1][1];
dp[i][1]=dp[i-1][0];
dp[i][2]=dp[i-1][1]+10*dp[i-1][2];

dp[i][2]的方程一开始写错了···   蛋疼大哭

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include <algorithm>#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)<(y)?(x):(y))#define ll long long#define eps 1e-8#define ms(x,y) (memset(x,y,sizeof(x)))#define fr(i,x,y) for(int i=x;i<=y;i++)using namespace std;ll dp[20][3];//0 不含49//1 首是9 但不含49//2 含49void make(){    ms(dp,0);    dp[0][0]=1;    fr(i,1,20)    {        dp[i][0]=10*dp[i-1][0]-dp[i-1][1];        dp[i][1]=dp[i-1][0];        dp[i][2]=dp[i-1][1]+10*dp[i-1][2];    }}ll ans(ll k){    ll a[25],s=0,flag=0,len=0;    while(k)    {        a[++len]=k%10;        k/=10;    }    a[len+1]=0;    for(int i=len;i>0;i--)    {        s+=dp[i-1][2]*a[i];        if(flag)s+=dp[i-1][0]*a[i];        else        {            if(a[i]>4)s+=dp[i-1][1];        }        if(a[i+1]==4&&a[i]==9)flag=1;    }    return s;}int main(){    make();    int T;    cin>>T;    while(T--)    {        ll n;        cin>>n;        cout<<ans(n+1)<<endl;    }    return 0;}


0 0
原创粉丝点击