首先,阅读题面,发现 ,于是我想到了暴搜,用vector记录当前选了哪些,中途如何过发现已经不合格了的话,那么就直接退出。枚举完一种情况以后就立刻回溯,继续枚举即可。
时间复杂度:。
具体实现可以参考我的代码:
#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;
}
本文描述了一种解决奶牛上船问题的递归算法,通过暴搜和剪枝优化,使用vector记录选择的奶牛并检查是否产生进位。时间复杂度取决于搜索过程。
3490

被折叠的 条评论
为什么被折叠?



