HDU6148 Valley Numer
题目大意:
思路
一道很明显的数位dp,不能出现先增后减这种情况,并且前导0是不合法,所以都需要额外的标志记录状态
代码
#include <bits/stdc++.h>
using namespace std;
#define me(a, b) memset(a, b, sizeof(a))
#define IOS() ios::sync_with_stdio(false), cin.tie(0)
#define endl '\n'
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const int maxn = 2e5 + 5;
const ll mod = 1e9 + 7;
int dp[2][2][3][10][101];
int n;
char s[105];
int dfs(int pos, int limit, int zero, int pre, int flag)
{
if(pos == n ) return 1;
if(dp[limit][zero][flag][pre][pos] != -1)
return dp[limit][zero][flag][pre][pos];
int ans = 0;
for(int i = 0; i < 10; ++i) {
int d = s[pos] - '0';
if(limit && i > d)
break;
if(i < pre && flag == 1) {
i = pre-1;
continue;
}
if(zero) {
ans += dfs(pos+1, limit&&i==d, i==0, i, 0);
}
else {
int x = flag;
if(i > pre) x = 1;
else if(i < pre) x = 2;
ans += dfs(pos+1, limit&&i==d, 0, i, x);
}
ans %= mod;
}
return dp[limit][zero][flag][pre][pos] = ans;
}
int solve()
{
me(dp, -1);
cin >> s;
n = strlen(s);
return (dfs(0, 1, 1, 0, 0) - 1 + mod) % mod;
}
int main()
{
IOS();
int T;
cin >> T;
while(T--) {
cout << solve() << endl;
}
return 0;
}
总结:
注意前导0以及递增和递减