HDU 6148 Valley Numer(数位DP)
题意:问小于n的数有多少个V型的数字
思路:定义dp[i][j][k]表示第i位,前一个数为j,k==0表示非上升,k==1表示上升,转移一下就好了
代码:
#include <bits/stdc++.h> using namespace std; typedef long long LL; const LL MOD = 1e9 + 7; LL dp[105][15][5]; char b[105]; int a[105]; LL dfs(int pos, int pre, int state, int limit) { // printf("st pos == %d pre == %d state == %d limit == %d\n", pos, pre, state, limit); if (pos == -1) { return 1; } if (!limit && dp[pos][pre][state] != -1) return dp[pos][pre][state]; int up = limit ? a[pos] : 9; LL res = 0; if (state) { for (int i = pre; i <= up; i++) { res += dfs(pos - 1, i, 1, limit && i == up); if(res >= MOD) res %= MOD; } } else { for (int i = 0; i <= up; i++) { if(i <= pre) { if(!i && pre == 10) res += dfs(pos - 1, 10, 0,limit && i == up); else res += dfs(pos - 1, i, 0, limit && i == up); } else{ res += dfs(pos - 1, i, 1, limit && i == up); } if(res >= MOD) res %= MOD; } } if(!limit) dp[pos][pre][state] = res; // printf("test pos == %d pre == %d state == %d limit == %d res == %lld\n", pos, pre, state, limit, res); return res; } LL solve() { int pos = strlen(b); for (int i = 0, j = pos - 1; i < pos; i++, j--) { a[i] = b[j] - '0'; } return dfs(pos - 1, 10, 0, true); } int main() { memset(dp, -1, sizeof(dp)); int T; scanf("%d", &T); while(T--) { scanf("%s", b); printf("%lld\n", (solve() - 1 + MOD) % MOD ); } return 0; } /* 3 3 14 120 */