[HDOJ6148] Valley Numer(数位dp)
Posted tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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\n"); 109 continue; 110 } 111 printf("%I64d\n", f()-1); 112 } 113 RT 0; 114 }
以上是关于[HDOJ6148] Valley Numer(数位dp)的主要内容,如果未能解决你的问题,请参考以下文章