1 条题解
-
0
解题思路
本题要求计算将 (n) 台电脑分配到 (k) 辆卡车上,且每辆卡车都有电脑(无空车)的分配方案数。
- 状态定义:使用二维数组
dp[i][j]
表示将 (j) 个物品分配到 (i) 个容器(本题中即 (i) 辆卡车,(j) 台电脑 )且无空容器的方案数。 - 边界条件初始化:
dp[i][i] = 1
,表示 (i) 个物品分配到 (i) 个容器,每个容器放一个,只有一种方案。dp[1][i] = 1
,表示将 (i) 个物品都放到 1 个容器中,也只有一种方案。dp[i][0] = dp[0][i] = 1
,可理解为一种特殊的边界定义,方便后续递推计算。
- 状态转移方程推导:对于
dp[i][j]
((i) 辆卡车分配 (j) 台电脑 ),可以从两个角度考虑:- 至少有一辆卡车只放 1 台电脑,此时方案数等同于把 (j - 1) 台电脑分配到 (i - 1) 辆卡车的方案数,即
dp[i - 1][j - 1]
。 - 每辆卡车至少放 2 台电脑,先给每辆卡车都放 1 台电脑,剩下 (j - i) 台电脑再分配到 (i) 辆卡车上,方案数为
dp[i][j - i]
。 - 所以状态转移方程为
dp[i][j] = dp[i - 1][j - 1] + dp[i][j - i]
。
- 至少有一辆卡车只放 1 台电脑,此时方案数等同于把 (j - 1) 台电脑分配到 (i - 1) 辆卡车的方案数,即
- 计算与输出:通过双重循环根据状态转移方程计算出所有可能的
dp[i][j]
值。在主函数中,不断读取输入的 (n) 和 (k) ,输出dp[k][n]
,即 (k) 辆卡车分配 (n) 台电脑的方案数。
#include<iostream> #include<cstring> // 添加缺少的头文件 using namespace std; long long dp[201][201],tdp[201][201]; int n,k; int main(){ while(cin>>n>>k&&(n||k)){ memset(tdp,0,sizeof(tdp)); memset(dp,0,sizeof(dp)); for(int i = 1; i <= n; i++) tdp[i][i] = dp[i][i] = 1; for(int i = 2; i <= k; i++){ for(int j = 1; j <= n; j++) for(int l = 1; l*i<=j; l++){ tdp[j][l] = 0; for(int m = l; m*(i-1) <= j-l; m++) tdp[j][l]+=dp[j-l][m]; } for(int j = 1; j <= n; j++) for(int l = 1; l*i<=j; l++) dp[j][l] = tdp[j][l]; } long long res = 0; // 修正类型名拼写错误 for(int i = 1; i*k<=n; i++) res += dp[n][i]; cout << res << endl; } }
- 状态定义:使用二维数组
- 1
信息
- ID
- 284
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 17
- 已通过
- 1
- 上传者