马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
一、题目检察
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;
- }
复制代码 四、测试结果
|