1. 程式人生 > 實用技巧 >Valley Numer 【HDU - 6148】【數位DP】

Valley Numer 【HDU - 6148】【數位DP】

題目連結

很明顯的,有“大於”和“小於等於”兩種情況,且一旦“大於”了,只能繼續“大於”下去,如果“小於等於”,還可以選擇任意一種情況。於是乎,直接數位dp,並且記錄這一位是“大於狀態”還是“小於等於狀態”,就可以進行記憶化了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <string>
 5 #include <cstring>
 6 #include <algorithm>
 7 #include <limits>
 8
#include <vector> 9 #include <stack> 10 #include <queue> 11 #include <set> 12 #include <map> 13 #include <bitset> 14 #include <unordered_map> 15 #include <unordered_set> 16 #define lowbit(x) ( x&(-x) ) 17 #define pi 3.141592653589793 18 #define e 2.718281828459045 19
#define INF 0x3f3f3f3f 20 #define HalF (l + r)>>1 21 #define lsn rt<<1 22 #define rsn rt<<1|1 23 #define Lson lsn, l, mid 24 #define Rson rsn, mid+1, r 25 #define QL Lson, ql, qr 26 #define QR Rson, ql, qr 27 #define myself rt, l, r 28 #define pii pair<int, int> 29 #define MP(a, b) make_pair(a, b) 30
using namespace std; 31 typedef unsigned long long ull; 32 typedef unsigned int uit; 33 typedef long long ll; 34 const int maxN = 1e2 + 7; 35 const ll mod = 1e9 + 7; 36 void MOD(ll & x) { x >= mod ? x %= mod : x; } 37 char s[maxN]; 38 int N, dig[maxN]; 39 ll dp[maxN][10][2]; 40 ll dfs(int pos, int x, bool op, bool top, bool zero) 41 { 42 if(pos == 1) return !zero; 43 if(!top && (~dp[pos][x][op])) return dp[pos][x][op]; 44 ll sum = 0; 45 int u = top ? dig[pos - 1] : 9; 46 for(int i = 0; i <= u; i ++) 47 { 48 if(op) 49 { 50 if(i < x) continue; 51 sum += dfs(pos - 1, i, true, top && i == u, zero && (!i)); 52 MOD(sum); 53 } 54 else 55 { 56 sum += dfs(pos - 1, i, !zero && i > x, top && i == u, zero && (!i)); 57 MOD(sum); 58 } 59 } 60 if(!top && !zero) dp[pos][x][op] = sum; 61 return sum; 62 } 63 int main() 64 { 65 int T; scanf("%d", &T); 66 while(T --) 67 { 68 scanf("%s", s); 69 N = (int)strlen(s); 70 for(int i = 0; i < N; i ++) dig[N - i] = s[i] - '0'; 71 memset(dp, -1, sizeof(dp)); 72 printf("%lld\n", dfs(N + 1, 0, false, true, true)); 73 } 74 return 0; 75 }