题意:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/adab2ddada1284d4c7a23fdfd09cd316.png)
解法:
数位dp.
显然数字排序后一定是非递减的.
对于22345,可以拆分为:
11111
11111
111
11
1
发现第i行中1的个数就是>=i的数字个数.
因此数字i的贡献就是[1,X]中>=i的数字个数.
从[1,9]枚举j,令d[i][k][l]表示高i位,>=j的数有k个,最高位限制为l的方案数.
枚举下一位的数字选择,dp一下即可.
对于固定的j,ans+=p[k]*(d[n][k][0]+d[n][k][1]),其中p[k]为k个连续1的值.
code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=700+5;
const int mod=1e9+7;
int d[maxm][maxm][2];
int p[maxm];
char s[maxm];
int n;
signed main(){
ios::sync_with_stdio(0);
for(int i=1;i<maxm;i++)p[i]=(p[i-1]*10+1)%mod;
cin>>(s+1);
n=strlen(s+1);
for(int i=1;i<=n;i++)s[i]-='0';
int ans=0;
for(int j=1;j<=9;j++){
memset(d,0,sizeof d);
for(int x=0;x<=s[1];x++){
d[1][x>=j][x==s[1]]++;
}
for(int i=1;i<=n-1;i++){
for(int k=0;k<=i;k++){
for(int l=0;l<2;l++){
if(!d[i][k][l])continue;
int ma=(l?s[i+1]:9);
for(int x=0;x<=ma;x++){
d[i+1][k+(x>=j)][l&&(x==ma)]+=d[i][k][l];
d[i+1][k+(x>=j)][l&&(x==ma)]%=mod;
}
}
}
}
for(int k=0;k<=n;k++){
ans+=p[k]*(d[n][k][0]+d[n][k][1])%mod;
ans%=mod;
}
}
cout<<ans<<endl;
return 0;
}