ALG0 1004-无聊的逗
题意
他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的情况下长度最长是多少。
思路
这个题简化一下的版本是,
leetcode416:给你一个 只包含正整数的非空数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
用的01背包,判断是否能凑满和的一半
这道题需要枚举所有的状态,n个数中选多少个数,这些数能凑出等和子集,取最大值
代码
#include <iostream>
#include <vector>
using namespace std;
const int N = 18;
int a[N];
bool dp(vector<int> nums, int sum)
{
bool f[200010];
if(sum % 2) return false;
f[0] = true;
for(int i = 0; i < nums.size(); i ++ )
for(int j = sum / 2; j >= nums[i]; j --)
f[j] = f[j] | f[j - nums[i]];
if(f[sum / 2]) return true;
return false;
}
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i ++ )
cin >> a[i];
int ans = 0;
for(int i = 0; i < 1 << n; i ++ )
{
vector<int> nums;
for(int j = 0; j < n; j ++ )
if(i >> j & 1) nums.push_back(a[j]);
int sum = 0;
for(int i = 0; i < nums.size(); i ++ ) sum += nums[i];
if(dp(nums, sum)) ans = max(ans, sum / 2);
}
cout << ans;
return 0;
}