摘要:
子集枚举问题中每一个元素往往只有两种状态,如有或者无,左脑处理还是右脑处理等等,总之只有两种选择。可以利用dfs进行递归的枚举搜索。
问题描述:
传送门:
2392考前临时抱佛脚
算法分析:
由于每一个题在处理时,要么由左脑负责,要么由右脑负责,因此是一个典型的 2 n 2^n 2n型枚举问题。可以用dfs实现
当然在dfs时也可以加入适当的剪枝操作
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define INF (1<<20)
#pragma warning(disable:4996)
class Solution {
public:
vector<int> s;
vector<int> v[4];
long long int res = 0;
void function() {
for (int i = 0; i < 4; ++i)
{
int x; cin >> x;
s.push_back(x);
}
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < s[i]; ++j) {
int x;
cin >> x;
v[i].push_back(x);
}
}
for (int i = 0; i < 4; ++i)
{
int ans = INF;
dfs(ans, 0, 0, 0, v[i]);
res += ans;
}
cout << res << '\n';
}
void dfs(int& ans,int left,int right,int i,vector<int>& vv) {
if (i == vv.size())
{
ans = min(ans, max(left, right));
return;
}
if (min(left, right) >= ans) //减剪枝作
return;
dfs(ans, left + vv[i], right,i+1, vv); //子集枚举问题
dfs(ans, left, right + vv[i], i+1,vv);
}
};
int main() {
//freopen("in.txt", "r", stdin);
Solution s;
s.function();
return 0;
}