1 条题解
-
0
#include<bits/stdc++.h> using namespace std; typedef long long LL; LL f[1100][1100];//f[i][j]表示i个球放入j个相同盒子的方案数(允许某些盒子的球数为0) int main() { int n,m;scanf("%d%d",&n,&m);n-=m;//提前给每个盒子放入1个球 memset(f,0,sizeof f); for(int i=0;i<=n;i++) f[i][1]=1;//i个球放入1个盒子,只有1种方案 for(int j=1;j<=m;j++) f[0][j]=1;//0个球放入j个盒子,只有1种方案 for(int i=1;i<=n;i++) for(int j=2;j<=m;j++) { for(int k=0;k<=i/j;k++) f[i][j]+=f[i-k*j][j-1]; //i个球放入j个盒子,第1个盒子放k个(后面每个盒子都放k个) } printf("%lld",f[n][m]); return 0; }/* f[i][j]表示数字i分成j份有几种分法(i个球放进j个盒子) f[i][j]=f[i-j][1]+f[i-j][2]………f[i-j][j-1]+f[i-j][j] 解释:每个盒子放一个球(确保每个盒子都有球), 剩下的球分成1份或2份或3份……或j份 ,分完叠加到后面的盒子中。 注意状态转移方程还可以更加优美: f[i][j]=f[i-j][1] +f[i-j][2]……… f[i-j][j-1]+f[i-j][j] (1式) f[i-1][j-1]=f[(i-1)-(j-1)][1]+f[(i-1)-(j-1)][2]………f[(i-1)-(j-1)][j-1] 因为 (i-1)-(j-1)等于i-j,所以得到 f[i-1][j-1]=f[i-j][1]+f[i-j][2]………f[i-j][j-1] (2式) 把2式代入1式,得到:f[i][j]=f[i-1][j-1]+f[i-j][j] #include <bits/stdc++.h> using namespace std; typedef long long LL; LL f[1100][1100]; // f[i][j]表示数字i分成j份有几种分法 int main() { int n, m; scanf("%d%d", &n, &m); memset(f, 0, sizeof f); for (int i = 1; i <= n; i++) f[i][1] = 1; for (int i = 1; i <= n; i++) for (int j = 2; j <= m && j <= i; j++) { if (i == j) f[i][j] = 1; else { for (int k = 1; k <= j && k <= i - j; k++) f[i][j] += f[i - j][k]; } } printf("%lld", f[n][m]); return 0; } */ #include <bits/stdc++.h> using namespace std; typedef long long LL; LL f[1100][1100]; int main() { int n, m; scanf("%d%d", &n, &m); memset(f, 0, sizeof f); for (int i = 1; i <= n; i++) f[i][1] = 1; for (int i = 1; i <= n; i++) for (int j = 2; j <= m && j <= i; j++) { f[i][j] = f[i - 1][j - 1] + f[i - j][j]; } printf("%lld", f[n][m]); return 0; }
- 1
信息
- ID
- 622
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 8
- 标签
- 递交数
- 255
- 已通过
- 38
- 上传者