HDU 6148 数位DP

来源:互联网 发布:如何给网站做排名优化 编辑:程序博客网 时间:2024/05/29 14:07

Valley Numer

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 492    Accepted Submission(s): 259


Problem Description
众所周知,度度熊非常喜欢数字。

它最近发明了一种新的数字:Valley Number,像山谷一样的数字。




当一个数字,从左到右依次看过去数字没有出现先递增接着递减的“山峰”现象,就被称作 Valley Number。它可以递增,也可以递减,还可以先递减再递增。在递增或递减的过程中可以出现相等的情况。

比如,1,10,12,212,32122都是 Valley Number。

121,12331,21212则不是。

度度熊想知道不大于N的Valley Number数有多少。

注意,前导0是不合法的。
 

Input
第一行为T,表示输入数据组数。

每组数据包含一个数N。

● 1≤T≤200

● 1≤length(N)≤100
 

Output
对每组数据输出不大于N的Valley Number个数,结果对 1 000 000 007 取模。
 

Sample Input
3314120
 

Sample Output
314119
 

Source
2017百度之星程序设计大赛 - 复赛
 

题意 : 定义一种数叫做山峰数,如题所示。很明显的是一道数位DP题

它不可以先增后减,所以我们需要有三种状态,一种是增状态,一种是减状态,一种是初始状态(或不增不减)

这三种状态分别用数字 3 2 4 表示,所以要不出现先减后增的话,就是不记录先3后2这种情况,其他的都记录下来。

DP[当前位][前一位数的值][当前状态]  

一开始状态默认为 4 ,然后出现了非0数之后令它为 2 状态,因为可以先2后3,而不能先3后二,如果一开始就赋值3的话,单调递减的情况会被认为是不符合的,所以要设为2,然后接下来的每次都拿当前数字去和前一位数比较,判断它是增还是减,出了先增后减的情况以外,其他都计数就行了。

#include<cstdio>#include<iostream>#include<algorithm>#include<string.h>using namespace std;#define ll long long#define mod 1000000007char num[200];ll dp[150][15][5];ll wei[150];int len;ll dfs(ll pos,ll pre,ll now,ll flag){if(pos < 0){if(now == 4)return 0;return 1; }if(!flag && dp[pos][pre][now] != -1)return dp[pos][pre][now];ll up = flag ? wei[pos] : 9;ll sum = 0;for(int i = 0;i <= up;i++){if(now == 3 && pre <= i){sum += dfs(pos - 1,i,now,flag && i == up) % mod;sum %= mod;}if(now == 2){if(pre >= i){sum += dfs(pos - 1,i,now,flag && i == up) % mod;sum %= mod; }else{sum += dfs(pos - 1,i,3,flag && i == up) % mod;}}if(now == 4){if(i == 0){sum += dfs(pos - 1,i,now,flag && i == up) % mod;sum %= mod;}else{sum += dfs(pos - 1,i,2,flag && i == up) % mod;sum %= mod;}} } if(!flag)dp[pos][pre][now] = sum;return sum;}int main(){int t;scanf("%d",&t);while(t--){memset(dp,-1,sizeof(dp));scanf("%s",num);len = strlen(num);reverse(num,num + len);for(int i = 0;i < len;i++){wei[i] = num[i] - '0';}ll ans = dfs(len - 1,0,4,1) % mod;printf("%lld\n",ans);}return 0;}


原创粉丝点击