题意
考虑所有的正整数可重集
{a1,a2,a3...ak}
{
a
1
,
a
2
,
a
3
.
.
.
a
k
}
,满足
a1+a2...+ak=n
a
1
+
a
2
.
.
.
+
a
k
=
n
,求所有
ak1+ak2...+amk
a
1
k
+
a
2
k
.
.
.
+
a
k
m
的和。
n,m,k<=4096
n
,
m
,
k
<=
4096
分析
先做一次整数划分dp,也就是f[i,j]表示选了i个数和为j的方案。
然后分别考虑
[1,n]
[
1
,
n
]
中的每一个数对答案的贡献。
不难发现数
i
i
在答案中的系数为。
也就是
∑jf[k−j,n−i∗j]
∑
j
f
[
k
−
j
,
n
−
i
∗
j
]
。
时间复杂度
O(n2)
O
(
n
2
)
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=4105;
const int MOD=1000000007;
int n,m,k,f[N][N];
void mod(int &x) {x-=x>=MOD?MOD:0;}
int ksm(int x,int y)
{
int ans=1;
while (y)
{
if (y&1) ans=(LL)ans*x%MOD;
x=(LL)x*x%MOD;y>>=1;
}
return ans;
}
int main()
{
scanf("%d%d%d",&n,&k,&m);
f[0][0]=1;
for (int i=1;i<=k;i++)
for (int j=i;j<=n;j++)
mod(f[i][j]=f[i-1][j-1]+f[i][j-i]);
int ans=0;
for (int i=1;i<=n;i++)
{
int s=0;
for (int j=1;j<=k&&j*i<=n;j++) mod(s+=f[k-j][n-i*j]);
mod(ans+=(LL)s*ksm(i,m)%MOD);
}
printf("%d",ans);
return 0;
}