众所周知,度度熊非常喜欢数字。
它最近发明了一种新的数字: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
3
3
14
120
Sample Output
3
14
119
我这里算的是只要出现波峰就算不符合,然后用总的相减就好
代码有解释
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int dp[110][10][4];
const int mod = 1e9+7;
string s;
ll dfs(int pos,int zero,int pre,int flag,int shang,int f)
{
if(pos<0)
{
if(!zero&&f==1) return 1;
//没有前导0并且出现波峰那么返回1,其实出现波峰肯定没有前导0了
return 0;
}
if(!zero&&dp[pos][pre][shang]!=-1&&!flag) return dp[pos][pre][shang];
int up=flag?s[pos]-'0':9;
ll res=0;
for(int i=0;i<=up;i++)
{
if(zero&&i==0)
{
res+=dfs(pos-1,1,0,flag&&i==up,shang,0);
res%=mod;
}
else {
if(shang==3)
{
res+=dfs(pos-1,0,i,flag&&i==up,3,1);//出现过一个波峰,那么全都可以算
continue;
}
if(i==pre)
res+=dfs(pos-1,0,i,flag&&i==up,shang,f);//和上一个数相同不影响上还是下
else if(i>pre&&shang==0&&zero==1)
res+=dfs(pos-1,0,i,flag&&i==up,1,0); //如果有前导0还要上那么就上升一次
else if(i>pre&&shang==0&&!zero)
res+=dfs(pos-1,0,i,flag&&i==up,2,0);//如果没有前导0那么直接上升两次,这是为了避免10这种情况
else if(i>pre&&shang==1) res+=dfs(pos-1,0,i,flag&&i==up,2,0);//如果上升过一次,那么还要上升一次才能算下降,因为
//我的第一个数的前一个数是0,所以要消除这个的影响
else if(i<pre&&shang==2) res+=dfs(pos-1,0,i,flag&&i==up,3,1);
//如果上升完了下降那么f=1 即出现波峰
else {
res+=dfs(pos-1,0,i,flag&&i==up,shang,f);
}
res%=mod;
}
}
if(!zero&&!flag)
{
dp[pos][pre][shang]=(res%mod);
}
return res;
}
int main()
{
int T;
scanf("%d",&T);
memset(dp,-1,sizeof(dp));
while(T--)
{
cin>>s;
int len=s.length();
ll aa=0;
for(int i=0;i<len;i++)
{
aa=aa*10+(s[i]-'0');
aa%=mod;
}
if(len==1)
{
printf("%d\n",s[0]-'0');
continue;
}
reverse(s.begin(),s.end());
ll ww=dfs(len-1,1,0,1,0,0);
printf("%lld\n",(aa-ww+mod)%mod);
}
return 0;
}
正着做就是傻逼题了。。我是傻逼。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[110][12][2];
string s;
const int mod = 1e9+7;
ll dfs(int pos,int zero,int pre,int flag,int sh)
{
if(pos<0) return zero==0;
if(!flag&&dp[pos][pre][sh]!=-1&&!zero) return dp[pos][pre][sh];
int up=flag?s[pos]-'0':9;
ll res=0;
for(int i=0;i<=up;i++)
{
if(zero&&i==0) res+=dfs(pos-1,1,pre,flag&&i==up,sh);
else
{
if(i==pre) res+=dfs(pos-1,0,i,flag&&i==up,sh);
if(i>pre) res+=dfs(pos-1,0,i,flag&&i==up,1);
if(i<pre&&!sh) res+=dfs(pos-1,0,i,flag&&i==up,sh);
}
res%=mod;
}
if(!flag)
dp[pos][pre][sh]=res;
return res%mod;
}
int main()
{
int t;
scanf("%d",&t);
memset(dp,-1,sizeof(dp));
while(t--)
{
cin>>s;
reverse(s.begin(),s.end());
printf("%lld\n",dfs(s.length()-1,1,10,1,0) );
}
}