Valley Numer
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1402 Accepted Submission(s): 713
Problem Description
众所周知,度度熊非常喜欢数字。
它最近发明了一种新的数字:Valley Number,像山谷一样的数字。
当一个数字,从左到右依次看过去数字没有出现先递增接着递减的“山峰”现象,就被称作 Valley Number。它可以递增,也可以递减,还可以先递减再递增。在递增或递减的过程中可以出现相等的情况。
比如,1,10,12,212,32122都是 Valley Number。
121,12331,21212则不是。
度度熊想知道不大于N的Valley Number数有多少。
注意,前导0是不合法的。
它最近发明了一种新的数字: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
每组数据包含一个数N。
● 1≤T≤200
● 1≤length(N)≤100
Output
对每组数据输出不大于N的Valley Number个数,结果对 1 000 000 007 取模。
Sample Input
3
3
14
120
Sample Output
3
14
119
Source
思路:这应该算一道比较简单的数位dp题,数位dp入门题,刚学数位dp,还不是很熟,敲这题时,忘了考虑前导0的情况,参考了博客才知道自己错哪了。
定义一个dp[i][j][k],i表示位置,j表示前一位,k表示单调性,0表示未知,1表示上升,2表示下降。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<set> #include<cmath> #include<list> #include<deque> #include<cstdlib> #include<bitset> #include<stack> #include<map> #include<queue> using namespace std; typedef long long ll; const int INF=0x3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-6; const ll mod=1e9+7; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} string s; ll a[105],dp[105][10][5]; ll dfs(int pos,int pre,int turn,bool limit,bool invalid) {//pos为位置,turn为1表示上升,2下降,0未知,limit记录数位是否达上界,invalid记录前导是否都为0 if(pos==-1) return invalid?0:1; //如果全部为0,不合法返回0,否则返回1 if(!limit&&dp[pos][pre][turn]!=-1) return dp[pos][pre][turn]; //被记忆过了 int up=limit?a[pos]:9; //是否达上界 ll ans=0; for(int i=0;i<=up;i++) { if(turn==1&&i<pre) continue; int x; if(i==pre) x=turn; else if(i>pre) x=1; else x=2; if(invalid) x=0; ans=(ans+dfs(pos-1,i,x,limit&&i==a[pos],i==0&&invalid))%mod; } if(!limit) dp[pos][pre][turn]=ans; //记忆化 return ans; } ll solve(string x) { int pos=0; for(int i=x.length()-1;i>=0;i--) a[pos++]=x[i]-'0'; return dfs(pos-1,0,0,true,true); } int main() { ios_base::sync_with_stdio(false); cin.tie(0); int T; cin>>T; while(T--) { string s; memset(dp,-1,sizeof(dp)); cin>>s; cout<<solve(s)<<endl; } return 0; }