标签(空格分隔): 数位DP
题目链接
开始递增后就不能递减了
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int mod=1e9+7;
int T,n[105],f[105][11][2];char s[105];
void MOD(int &x,int y)
{
x+=y;
if(x>=mod)x-=mod;
}
int dp(int step,int last,int k,int lim)
{
if(step==0)return 1;
if(!lim&&~f[step][last][k])return f[step][last][k];
int x=lim?n[step]:9,res=0;
for(int i=0;i<=x;i++)
{
if(k&&i<last)continue;
int nt=(i==0&&last==10?10:i);
MOD(res,dp(step-1,nt,k||(i>last&&last!=10),lim&&i==x));
}
if(!lim)f[step][last][k]=res;
return res;
}
int main()
{
memset(f,-1,sizeof(f));
T=read();
for(int kase=1;kase<=T;kase++)
{
scanf("%s",s+1);
int len=strlen(s+1);
for(int i=1;i<=len;i++)n[i]=s[len-i+1]-'0';
int ans=0;
for(int i=0;i<=n[len];i++)MOD(ans,dp(len-1,i==0?10:i,0,i==n[len]));
printf("%d
",((ans-1)%mod+mod)%mod);
}
return 0;
}