数位DP——HDU6148 Valley Number

来源:互联网 发布:linux ps和netstat 编辑:程序博客网 时间:2024/05/22 01:35

题面:hdu6148
比赛的时候调到快结束的时候才A掉。。。(我真是太弱了。。。
其实就是数位DP,状态也很简单:
f[i][j][k]表示i位数字开头数字为j,当前状态为k的数量,k=1表明已经有过递增,k=0表明没有过递增。。。
然后先把f求出来之后直接统计答案就行了
还是很简单的。。。要是早调出来几分钟说不定文化衫就有了呢QAQ

#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#include <iostream>#include <ctime>#include <map>#include <queue>#include <cstdlib>#include <string>#include <climits>#include <set>#include <vector>#define int long longusing namespace std;const int MOD=1e9+7;int f[1010][10][2];char s[1010];inline int dp(){    scanf("%s",s+1);int l=strlen(s+1);    if(l==1)return s[1]-'0';    int ans=0;    for(int i=1;i<l;i++)        for(int j=1;j<10;j++)(ans+=f[i][j][0]+f[i][j][1])%=MOD;    int flag=0;    for(int i=1;i<l;i++){        int now=s[i]-'0';        for(int j=0;j<now;j++)if(i!=1||j!=0){            if(flag==1&&j-s[i-1]+'0'<0)continue;            (ans+=f[l-i+1][j][0])%=MOD;            if((i==1)||(!flag&&j-s[i-1]+'0'<=0))(ans+=f[l-i+1][j][1])%=MOD;        }                if((i>1)&&s[i]-s[i-1]<0&&flag){flag=2;break;}        if((i>1)&&s[i]-s[i-1]>0)flag=1;    }    if(flag<2){        int now=s[l]-'0';            if(flag<2)for(int j=0;j<=now;j++){            if(flag==1&&j-s[l-1]+'0'<0)continue;            (ans+=f[1][j][0])%=MOD;        }    }    return ans;}signed main(){    for(int i=0;i<10;i++)f[1][i][0]=1;    for(int i=2;i<=100;i++)        for(int j=0;j<10;j++)            for(int k=0;k<10;k++){                if(j>k)(f[i][j][1]+=f[i-1][k][0]+f[i-1][k][1])%=MOD;                if(j==k)(f[i][j][0]+=f[i-1][k][0],f[i][j][1]+=f[i-1][k][1])%=MOD;                if(j<k)(f[i][j][0]+=f[i-1][k][0])%=MOD;            }    int T;scanf("%I64d",&T);    while(T--)printf("%I64d\n",dp());    return 0;}
原创粉丝点击