题目描述见链接 .
设 表示将 划分为 份的方案数, .
发现这样会使得形如 1 1 3
. 的方案算多次: 1 1 3, 1 3 1, 3 1 1
.
设 表示将 划分成 份的方案数, 转移时不再一个一个数字添加, 而是整体往上叠,
可得 , 分别表示包含 和 不包含 的情况 .
初值: , 时间复杂度 .
鉴于上方的 方式, 统计答案不能按传统顺序统计, 那么怎么统计呢
我们可以对数字 单独考虑, 设 出现 次 的方案为 ,
则 .
而 .
到这一步, 发现求出 对统计答案好像并没有作用,
只需计算出 即可.
于是答案等于 , 统计答案时间复杂度同样是 .
#include<bits/stdc++.h>
#define reg register
const int maxn = 5005;
const int mod = 1e9 + 7;
int N;
int K;
int M;
int Ans;
int F[maxn][maxn];
int Ksm(int a, int b){ int s = 1; while(b){ if(b&1)s=1ll*s*a%mod; a=1ll*a*a%mod; b>>=1;} return s; }
int main(){
scanf("%d%d%d", &N, &K, &M);
F[0][0] = 1;
for(reg int i = 0; i <= N; i ++) F[i][i] = 1;
for(reg int j = 1; j <= K; j ++)
for(reg int i = j; i <= N; i ++)
F[i][j] = (F[i-1][j-1] + F[i-j][j]) % mod;
for(reg int i = 1; i <= N; i ++)
for(reg int j = 1; j <= K; j ++){
int num = 0;
if(i*j <= N) num += F[N-i*j][K-j];
int Amp = 1ll*num*Ksm(i, M) % mod;
Ans = (Ans + Amp) % mod;
}
printf("%d
", Ans);
return 0;
}