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;
}
posted @ 2022-03-18 18:44  inss!w!  阅读(30)  评论(0编辑  收藏  举报