给n<=10^700,问1到n中每个数在各数位排序后得到的数的和。答案膜1e9+7。
一看就是数位DP啦。。然而并没有什么思路。。
可以尝试统计n(i,j)表示数j在第i位的出现次数,知道了这个数组后就可以算答案了。可以枚举j,做一次DP,f(a,b,0/1)--考虑第a~n个数,有b个j,是否大于给定数字(因为当前大于给定数字不一定dp到前面的数就大于,所以当前大于给定数字的数也是有贡献的),等等光知道有多少j并不能确定第i位是否有j,行不通。
套路--k(i,j)表示第i位出现的>=j的数字的出现次数,则$n(i,j)=k(i,j)-k(i,j+1)$。现在f(a,b,0/1)中的b则表示有b个>=j的数,那么就可以递推了。用$X_a$表示给定数字第a位是谁:
1、$j>X_a$:$f(a,b,0)=(f(a+1,b,0)+f(a+1,b,1))*X_a+f(a+1,b,0),f(a,b,1)=(f(a+1,b-1,0)+f(a+1,b-1,1))*(10-j)+(f(a+1,b,0)+f(a+1,b,1))*(j-X_a-1)+f(a+1,b,1)$
2、$j<=X_a$:$f(a,b,0)=(f(a+1,b,0)+f(a+1,b,1))*j+(f(a+1,b-1,0)+f(a+1,b-1,1))*(X_a-j)+f(a+1,b-1,0),f(a,b,1)=(f(a+1,b-1,0)+f(a+1,b-1,1))*(10-X_a-1)+f(a+1,b-1,1)$。
还没完,边界条件:1、$j>X_n$:$f(n,0,0)=X_a+1,f(n,0,1)=j-X_a-1,f(n,1,1)=10-j,f(n,1,0)=0$。
2、$j<=X_n$:$f(n,0,0)=j,f(n,0,1)=0,f(n,1,0)=X_n-j+1,f(n,1,1)=10-X_n-1$。
这些加一减一、取等取不等的特别注意。把<和=归在一类是之前在草稿纸上推过发现可以合的。
然后就没了。注意检查膜。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<map> 6 //#include<bitset> 7 #include<algorithm> 8 //#include<cmath> 9 using namespace std; 10 11 int n; 12 #define maxn 711 13 char s[maxn]; 14 const int mod=1e9+7; 15 int kk[maxn][12],f[maxn][maxn][2]; 16 int main() 17 { 18 scanf("%s",s+1); n=strlen(s+1); 19 for (int j=0;j<=9;j++) 20 { 21 int num=s[n]-‘0‘; 22 if (j>num) {f[n][0][0]=num+1; f[n][1][0]=0; f[n][0][1]=j-num-1; f[n][1][1]=10-j;} 23 else {f[n][0][0]=j; f[n][1][0]=num-j+1; f[n][0][1]=0; f[n][1][1]=10-num-1;} 24 25 for (int a=n-1;a;a--) 26 { 27 int num=s[a]-‘0‘; 28 if (j>num) 29 { 30 f[a][0][0]=(1ll*(f[a+1][0][0]+f[a+1][0][1])*num+f[a+1][0][0])%mod; 31 f[a][0][1]=(1ll*(f[a+1][0][0]+f[a+1][0][1])*(j-num-1)+f[a+1][0][1])%mod; 32 for (int b=1,to=n-a+1;b<=to;b++) 33 { 34 f[a][b][0]=(1ll*(f[a+1][b][0]+f[a+1][b][1])*num+f[a+1][b][0])%mod; 35 f[a][b][1]=(1ll*(f[a+1][b-1][0]+f[a+1][b-1][1])*(10-j) 36 +1ll*(f[a+1][b][0]+f[a+1][b][1])*(j-num-1)+f[a+1][b][1])%mod; 37 } 38 } 39 else 40 { 41 f[a][0][0]=(1ll*(f[a+1][0][0]+f[a+1][0][1])*j)%mod; 42 f[a][0][1]=0; 43 for (int b=1,to=n-a+1;b<=to;b++) 44 { 45 f[a][b][0]=(1ll*(f[a+1][b][0]+f[a+1][b][1])*j 46 +1ll*(f[a+1][b-1][0]+f[a+1][b-1][1])*(num-j)+f[a+1][b-1][0])%mod; 47 f[a][b][1]=(1ll*(f[a+1][b-1][0]+f[a+1][b-1][1])*(10-num-1)+f[a+1][b-1][1])%mod; 48 } 49 } 50 } 51 for (int i=n;i;i--) f[1][i][0]+=f[1][i+1][0],f[1][i][0]-=f[1][i][0]>=mod?mod:0,kk[i][j]=f[1][i][0]; 52 } 53 int ans=0; 54 for (int i=1,ten=1;i<=n;i++) 55 { 56 for (int j=0;j<=9;j++) 57 ans+=1ll*(kk[i][j]-kk[i][j+1]+mod)*ten%mod*j%mod, 58 ans-=ans>=mod?mod:0,ans+=ans<0?mod:0; 59 ten=1ll*ten*10%mod; 60 } 61 printf("%d\n",ans); 62 return 0; 63 }