AcWing-2050 逃离农场 题解

本文描述了一种解决奶牛上船问题的递归算法,通过暴搜和剪枝优化,使用vector记录选择的奶牛并检查是否产生进位。时间复杂度取决于搜索过程。

首先,阅读题面,发现 n \le 20,于是我想到了暴搜,用vector记录当前选了哪些,中途如何过发现已经不合格了的话,那么就直接退出。枚举完一种情况以后就立刻回溯,继续枚举即可。

时间复杂度:2^n

具体实现可以参考我的代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
int w[N], ans = -1;
vector<int> res;
int n;

bool check() { // 检查该情况是否合格
    vector<string> vec;
    for (auto x : res) {
        string s = to_string(x);
        reverse(s.begin(), s.end());
        vec.push_back(s);
    }
    for (int i = 0; i < 9; i++) {
        int sum = 0;
        for (auto x : vec) {
            if (i < x.size()) {
                sum += x[i] - '0';
            }
        }
        if (sum >= 10) // 有一列的值 >= 10,说明要进位,那么就是不合格
            return false;
    }
    return true; // 每一位都合格,表示这种情况没有问题
}

void dfs(int pos) { // pos 记录当前遍历到哪个位置了,并且这个位置还没有被遍历到
    if ((int)res.size() + (n - pos + 1) <= ans) { // 如果发现就算加上以后还没算过的也无法更新答案的话,就直接剪枝即可
        return;
    }
    if (check()) { // 看这种答案是否合格
        ans = max(ans, (int)res.size()); // 更新答案
    } else {
        return; // 提前发现不合格,直接剪枝
    }
    if (pos > n) {
        return; // 这种遍历完了,每一个数都已经考虑了,那么就退出
    }
    res.push_back(w[pos]); // 表示取当前的奶牛上船
    dfs(pos + 1);
    res.pop_back(); // 回溯
    dfs(pos + 1); // 表示跳过这头奶牛 (不取这头奶牛船) 
}

int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> w[i]; // 读入每头奶牛的重量
    }
    dfs(1); // 从编号为 1 的奶牛开始向后面搜索
    cout << ans << "\n"; // 输出答案
    return 0;
}

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值