版权声明:欢迎转载 https://blog.csdn.net/l18339702017/article/details/82942907
Valley NumerTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1199 Accepted Submission(s): 614 Problem Description 众所周知,度度熊非常喜欢数字。它最近发明了一种新的数字:Valley Number,像山谷一样的数字。 当一个数字,从左到右依次看过去数字没有出现先递增接着递减的“山峰”现象,就被称作 Valley Number。它可以递增,也可以递减,还可以先递减再递增。在递增或递减的过程中可以出现相等的情况。 比如,1,10,12,212,32122都是 Valley Number。 121,12331,21212则不是。 度度熊想知道不大于N的Valley Number数有多少。 注意,前导0是不合法的。 Input 第一行为T,表示输入数据组数。 Output 对每组数据输出不大于N的Valley Number个数,结果对 1 000 000 007 取模。 Sample Input 3 3 14 120 Sample Output 3 14 119 Source Recommend We have carefully selected several similar problems for you: 6447 6446 6445 6444 6443 |
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 110;
const int MOD = 1e9 + 7;
ll a[N], dp[N][10][3];
ll dfs(int pos, int pre, int flag, bool limit, bool inval){
//flag == 1 下降 flag == 2 上升
if(pos == -1) return inval ? 0 : 1;
if(!limit && dp[pos][pre][flag] != -1) return dp[pos][pre][flag];
int up = limit ? a[pos] : 9;
ll ans = 0LL;
for(int i=0; i<=up; i++){
if(flag == 2 && i < pre) continue;
int p = 0;
if(i == pre) p = flag;
else if(i < pre) p = 1;
else p = 2;
if(inval) p = 0;
ans += dfs(pos-1, i, p, limit && i == a[pos], inval && i == 0);
ans %= MOD;
}
ans %= MOD;
if(!limit) dp[pos][pre][flag] = ans;
return ans;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
memset(dp, -1, sizeof(dp));
char s[N];
scanf("%s", s);
int len = strlen(s);
for(int i=0; i<len; i++)
a[i] = s[len-1-i] - '0';
//倒着存
printf("%lld\n", dfs(len-1, 0, 0, true, true));
}
return 0;
}