hdu6148 Valley Numer

题目描述

题解:

数位$dp$模板题。

只需要记录上升下降,还有是否在边界上即可。

其中$f,g$是前缀和和后缀和。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 105
#define ll long long
#define MOD 1000000007
int T,len;
char s[N];
ll dp[N][12][2][2];
ll f[N][12][2][2],g[N][12][2][2];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",s+1);
        len = strlen(s+1);
        memset(dp,0,sizeof(dp));
        memset(f,0,sizeof(f));
        memset(g,0,sizeof(g));
        for(int i=1;i<=len;i++)
        {
            if(i==1)
            {
                dp[i][s[i]-'0'][0][0] = 1;
                for(int j=1;j<s[i]-'0';j++)
                    dp[i][j][1][0]++;
            }else
            {
                if(s[i-1]>s[i])
                    (dp[i][s[i]-'0'][0][0] += dp[i-1][s[i-1]-'0'][0][0])%=MOD;
                else if(s[i-1]<s[i])
                    (dp[i][s[i]-'0'][0][1] += dp[i-1][s[i-1]-'0'][0][1]+dp[i-1][s[i-1]-'0'][0][0])%=MOD;
                else
                {
                    (dp[i][s[i]-'0'][0][0] += dp[i-1][s[i-1]-'0'][0][0])%=MOD;
                    (dp[i][s[i]-'0'][0][1] += dp[i-1][s[i-1]-'0'][0][1])%=MOD;
                }
                for(int j=1;j<=9;j++)
                    dp[i][j][1][0]++;
            }
            for(int j=0;j<s[i]-'0';j++)
            {
                (dp[i][j][1][0]+=g[i-1][j][0][0])%=MOD;
                (dp[i][j][1][1]+=f[i-1][j][0][0]+f[i-1][j][0][1]-dp[i-1][j][0][0])%=MOD;
            }
            for(int j=0;j<=9;j++)
            {
                (dp[i][j][1][0]+=g[i-1][j][1][0])%=MOD;
                (dp[i][j][1][1]+=f[i-1][j][1][0]+f[i-1][j][1][1]-dp[i-1][j][1][0])%=MOD;
            }
            for(int j=0;j<=9;j++)
            {
                f[i][j][0][0]=(f[i][j-1][0][0]+dp[i][j][0][0])%MOD;
                f[i][j][0][1]=(f[i][j-1][0][1]+dp[i][j][0][1])%MOD;
                f[i][j][1][0]=(f[i][j-1][1][0]+dp[i][j][1][0])%MOD;
                f[i][j][1][1]=(f[i][j-1][1][1]+dp[i][j][1][1])%MOD;
            }
            for(int j=9;j>=0;j--)
            {
                g[i][j][0][0]=(g[i][j+1][0][0]+dp[i][j][0][0])%MOD;
                g[i][j][0][1]=(g[i][j+1][0][1]+dp[i][j][0][1])%MOD;
                g[i][j][1][0]=(g[i][j+1][1][0]+dp[i][j][1][0])%MOD;
                g[i][j][1][1]=(g[i][j+1][1][1]+dp[i][j][1][1])%MOD;
            }
        }
        ll ans = ((f[len][9][0][0]+f[len][9][0][1]+f[len][9][1][0]+f[len][9][1][1])%MOD+MOD)%MOD;
        printf("%lld\n",ans);
    }
    return 0;
}

 

posted @ 2019-01-11 16:23  LiGuanlin  阅读(131)  评论(0编辑  收藏  举报