直接写暴搜,然后过了
#include<cstdio>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
int ans, n, k;
void dfs(int i, int st, int sum)
{
if(i == k)
{
if(sum == n) ans++;
return;
}
REP(j, st, n)
{
if(sum + j > n) break;
dfs(i + 1, j, sum + j);
}
}
int main()
{
scanf("%d%d", &n, &k);
dfs(0, 1, 0);
printf("%d
", ans);
return 0;
}
还可以用动规
设f[i][j]为把i个数分为j个部分的方案
那么如果当前有1的话,f[i][j] = f[i-1][j-1]
没有的话,可以由把每一个部分全部减去1转移而来
即f[i][j] = f[i-j][j]
#include<cstdio>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
const int MAXN = 212;
int f[MAXN][10], ans, n, k;
int main()
{
scanf("%d%d", &n, &k);
REP(i, 0, n + 1) f[i][0] = f[i][1] = 1;
REP(i, 2, n + 1)
REP(j, 2, k + 1)
{
f[i][j] = f[i-1][j-1];
if(i > j) f[i][j] += f[i-j][j];
}
printf("%d
", f[n][k]);
return 0;
}