HDU 6148 Valley Numer 数位DP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6148

题意:如题。

解法:裸数位DP,dp[pos][pre][sta]表示当前在pos位,前一位的数字是pre,当前状态是上升还是下降的合法的数的个数。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 110;
const int mod = 1e9+7;
LL dp[maxn][12][2];
LL digit[maxn];
LL dfs(int pos, int sta, int pre, int lim)
{
    if(pos<1) return 1;
    if(!lim&&~dp[pos][pre][sta]) return dp[pos][pre][sta];
    int jud = lim?digit[pos]:9;
    LL ans = 0;
    if(sta){
        for(int i=pre; i<=jud; i++){
            ans += dfs(pos-1, 1, i, lim&&i==jud);
            ans %= mod;
        }
    }else{
        for(int i=0; i<=jud; i++){
            if(i>pre){
                ans += dfs(pos-1,1,i,lim&&i==jud);
                ans %= mod;
            }
            else{
                if(!i&&pre==10)
                    ans += dfs(pos-1,0,10,lim&&i==jud);
                else
                    ans += dfs(pos-1,0,i,lim&&i==jud);
                ans %= mod;
            }
        }
    }
    if(!lim) dp[pos][pre][sta] = ans;
    return ans;
}
LL f(char s[])
{
    int len = strlen(s);
    for(int i=0; i<len; i++){
        digit[len-i] = s[i]-'0';
    }
    return dfs(len, 0, 10, 1);
}
char s[110];
int main()
{
    memset(dp, -1, sizeof(dp));
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%s", s);
        printf("%lld\n", (f(s)-1+mod)%mod);
    }
    return 0;
}

 

posted @ 2017-08-30 21:26  zxycoder  阅读(122)  评论(0编辑  收藏  举报