[HDOJ6148] Valley Numer(数位dp)

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

经典数位dp,dp(l,pre,status)表示长度l,之前数字是pre,由什么状态转移过来的。

status有3个:0初始(就一次)1上升2下降,按要求分三个情况讨论转移就行了。

  1 /*
  2 ━━━━━┒ギリギリ♂ eye!
  3 ┓┏┓┏┓┃キリキリ♂ mind!
  4 ┛┗┛┗┛┃\○/
  5 ┓┏┓┏┓┃ /
  6 ┛┗┛┗┛┃ノ)
  7 ┓┏┓┏┓┃
  8 ┛┗┛┗┛┃
  9 ┓┏┓┏┓┃
 10 ┛┗┛┗┛┃
 11 ┓┏┓┏┓┃
 12 ┛┗┛┗┛┃
 13 ┓┏┓┏┓┃
 14 ┃┃┃┃┃┃
 15 ┻┻┻┻┻┻
 16 */
 17 #include <bits/stdc++.h>
 18 using namespace std;
 19 #define fr first
 20 #define sc second
 21 #define cl clear
 22 #define BUG puts("here!!!")
 23 #define W(a) while(a--)
 24 #define pb(a) push_back(a)
 25 #define Rint(a) scanf("%d", &a)
 26 #define Rll(a) scanf("%I64d", &a)
 27 #define Rs(a) scanf("%s", a)
 28 #define Cin(a) cin >> a
 29 #define FRead() freopen("in", "r", stdin)
 30 #define FWrite() freopen("out", "w", stdout)
 31 #define Rep(i, len) for(int i = 0; i < (len); i++)
 32 #define For(i, a, len) for(int i = (a); i < (len); i++)
 33 #define Cls(a) memset((a), 0, sizeof(a))
 34 #define Clr(a, x) memset((a), (x), sizeof(a))
 35 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 36 #define lrt rt << 1
 37 #define rrt rt << 1 | 1
 38 #define pi 3.14159265359
 39 #define RT return
 40 #define lowbit(x) x & (-x)
 41 #define onenum(x) __builtin_popcount(x)
 42 typedef long long LL;
 43 typedef long double LD;
 44 typedef unsigned long long ULL;
 45 typedef pair<int, int> pii;
 46 typedef pair<string, int> psi;
 47 typedef pair<LL, LL> pll;
 48 typedef map<string, int> msi;
 49 typedef vector<int> vi;
 50 typedef vector<LL> vl;
 51 typedef vector<vl> vvl;
 52 typedef vector<bool> vb;
 53 
 54 const LL mod = 1e9+7;
 55 const int maxn = 110;
 56 char s[maxn];
 57 LL dp[maxn][11][5];
 58 int len;
 59 int digit[maxn];
 60 
 61 LL dfs(int l, int pre, int status, int flag) {
 62     if(l == 0) return 1;
 63     if(!flag && dp[l][pre][status] != -1) return dp[l][pre][status];
 64     int pos = flag ? digit[l] : 9;
 65     LL ret = 0;
 66     for(int i = 0; i <= pos; i++) {
 67         if(status == 0) {
 68             ret += dfs(l-1, i, i!=0, flag&&(i==pos));
 69             ret %= mod;
 70         }
 71         if(status == 1) {
 72             if(i <= pre) {
 73                 ret += dfs(l-1, i, 1, flag&&(i==pos));
 74                 ret %= mod;
 75             }
 76             else {
 77                 ret += dfs(l-1, i, 2, flag&&(i==pos));
 78                 ret %= mod;
 79             }
 80         }
 81         else if(status == 2) {
 82             if(pre <= i) {
 83                 ret += dfs(l-1, i, 2, flag&&(i==pos));
 84                 ret %= mod;
 85             }
 86         }
 87     }
 88     if(!flag) dp[l][pre][status] = ret;
 89     return ret;
 90 }
 91 
 92 LL f() {
 93     int pos = 0;
 94     for(int i = len-1; i >= 0; i--) {
 95         digit[++pos] = s[i] - '0';
 96     }
 97     return dfs(pos, 0, 0, 1);
 98 }
 99 
100 signed main() {
101     // FRead();
102     int T;
103     Rint(T);
104     W(T) {
105         Clr(dp, -1);
106         Rs(s); len = strlen(s);
107         if(strcmp(s, "0") == 0) {
108             printf("1
");
109             continue;
110         }
111         printf("%I64d
", f()-1);
112     }
113   RT 0;
114 }
原文地址:https://www.cnblogs.com/kirai/p/7392065.html