题意: 找出满足条件,未出现山峰的数字
代码里见注释
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll mod=1000000007 ;
ll dp[200][10][5];
int digit[200];
// 1为 递增
// 2为 递减
// 3为 出现山峰
// 4为 出现过一个数字,还未出现过不同数字
// 0为 之前有零个数字
ll dfs(int len,int limit,int status,int pre)
{
if(len<0)
{
return 1;
}
if(!limit&&dp[len][pre][status]!=-1)
{
return dp[len][pre][status];
}
ll ans=0;
int last=9;
if(limit) last=digit[len];
for(int i=0;i<=last;i++)
{
if(status==0)
{
if(i==0)
ans+=dfs(len-1,limit&&i==last, 0, 0);
else
ans+=dfs(len-1,limit&&i==last, 4, i );
}
else if(status==1)
{
if(i==pre)
ans+=dfs(len-1,limit&&i==last,status,i);
if(i>pre)
ans+=dfs(len-1,limit&&i==last, 1,i);
}
else if(status==2)
{
if(i==pre)
ans+=dfs(len-1,limit&&i==last,status,i);
if(i<pre)
ans+=dfs(len-1,limit&&i==last,2,i);
if(i>pre)
ans+=dfs(len-1,limit&&i==last,1,i);
}
else if(status==4)
{
if(i==pre)
ans+=dfs(len-1,limit&&i==last,4,i );
if(i<pre)
ans+=dfs(len-1,limit&&i==last,2,i );
if(i>pre)
ans+=dfs(len-1,limit&&i==last,1,i );
}
ans%=mod;
}
if(!limit)
dp[len][pre][status]=ans;
return ans;
}
char s[200];
ll solve( )
{
int cnt=0;
int len=strlen(s);
for(int i=len-1;i>=0;i--)
digit[cnt++]=s[i]-'0';
return dfs( cnt-1, 1, 0 ,0) ;
}
int main()
{
memset(dp,-1,sizeof(dp));
int t;
scanf("%d",&t);
for(int cs=1;cs<=t;cs++)
{
ll l,r;
scanf("%s",s);
ll res=solve( )-1;
printf("%lld\n",res%mod );
}
}