一、题目查看
P10483 小猫爬山 - 洛谷
二、解题思路
我们将采取递归 + 剪枝的思想:
sum数组存放每辆车当前载重。
每次新考虑一只小猫时,我们尝试把它放进每个可以放进的缆车中(需要回溯)
for (int i = 0; i < k; i++) {if (sum[i] + c[u] <= w) {sum[i] += c[u];dfs(u + 1, k);sum[i] -= c[u];} }
我们还要再尝试为它单独新开一辆缆车,不然会错(也要回溯)
sum[k] = c[u]; dfs(u + 1, k + 1); // 再开一个缆车 sum[k] = 0;
最后我们需要更新答案和剪枝
if (k >= ans) return; // 如果缆车数量不如当前最佳答案直接剪枝 if (u == n) ans = k; // 小猫都装完了
三、代码
#include <bits/stdc++.h> using namespace std;const int N = 20; int c[N], sum[N]; int n, w, ans;void dfs(int u, int k) { // u = 第 u 只小猫, k = 缆车数量if (k >= ans) return; // 如果缆车数量不如当前最佳答案直接剪枝if (u == n) ans = k; // 小猫都装完了for (int i = 0; i < k; i++) {if (sum[i] + c[u] <= w) {sum[i] += c[u];dfs(u + 1, k);sum[i] -= c[u];}}sum[k] = c[u];dfs(u + 1, k + 1); // 再开一个缆车sum[k] = 0; }int main() {cin >> n >> w;ans = n;for (int i = 0; i < n; i++) {cin >> c[i];}dfs(0, 0);cout << ans;return 0; }
四、测试结果