版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42391248/article/details/85198805
我们用dp[i][j]表示的是前i位的数字和为j,j最大为9*i ,前i位每位都是9的时候。 这样假如我们求得了dp[n][1]一直到dp[n][9*n]的数字,那么最终结果就是dp[n][1] * dp[n][1] + ... + dp[n][9*n] * dp[n][9*n] . 但是这里还有一个问题就是,dp[i][j] 表示的是前i位的数字和为j,但是我们知道前面的那个 i位 是 不能有前置0的,所以还有处理一下。
求结果的时候就是sum(有前置0的结果)*(不含前置0的结果)。没有前置0的结果是 dp[i][j] - dp[i-1][j] , 因为每次都是在前面加数字,所以要是i位和i-1位的和一样,就是前置0的数字了。
接下来就是怎么求解dp[i][j] 了, dp[i][j]+= dp[i-1][j-k] ; (j>=k,k=0,1,2...9) .很好理解 。
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int Mod=1e9+7;
long long dp[1005][9045];//前i个数的和为j
int main()
{
int i,j,k;
memset(dp,0,sizeof(dp));
for(i=0;i<=9;i++)
dp[1][i]=1;
for(i=2;i<=1000;i++)
for(j=0;j<=i*9;j++)
for(k=0;k<=9;k++)
if(j>=k)
dp[i][j]=(dp[i][j]+dp[i-1][j-k])%Mod;
int n;
long long sum=0;
cin>>n;
for(i=1;i<=9*n;i++)
sum=(sum+(dp[n][i]-dp[n-1][i])*dp[n][i])%Mod;
cout<<sum<<endl;
return 0;
}