首页 > 编程语言 >Problem P32. [算法课分支限界法]Partition to K Equal Sum Subsets

Problem P32. [算法课分支限界法]Partition to K Equal Sum Subsets

时间:2022-10-10 15:56:16浏览次数:56  
标签:arr return cur Subsets nums int Sum vector 限界

纯暴力遍历+剪枝,将任务看出有k个桶,要将每个桶都刚刚好装满。

#include<iostream>
#include<bits/stdc++.h>
#include<cstdio>
#include<string>

using namespace std;

static bool dfs(vector<int>& nums, int cur, vector<int>& arr, int k) {
    //已经遍历到了-1说明前面的所有数都正好可以放入桶里,那所有桶的值此时都为0,说明找到了结果,返回true
    if (cur < 0){
        return true;
    }
    // 遍历 k 个桶
    for (int i = 0; i < k; i++){
        if (i && arr[i] == arr[i-1]) {
            continue;
        }
        // 如果正好能放下当前的数或者放下当前的数后,还有机会放前面的数(剪枝)
        if (arr[i] == nums[cur] || (cur > 0 && arr[i] - nums[cur] >= nums[0])){
            // 放当前的数到桶i里
            arr[i] -= nums[cur];
            // 开始放下一个数
            if (dfs(nums, cur-1, arr, k)){
                return true;
            }
            // 这个数不放在桶i里
            arr[i] += nums[cur];
        }
    }
    return false;
}
static bool canPartitionKSubsets(vector<int>& nums, int k) {
    int sum = accumulate(nums.begin(), nums.end(), 0);
    if (sum % k != 0){
        return false;
    }
    int per = sum / k;
    sort(nums.begin(), nums.end());
    if (nums.back() > per){
        return false;
    }
    // 建立一个长度为 k 的桶, 桶里的每个值都是子集的和
    vector<int> arr = vector<int>(k, per);
    // 从数组最后一个数开始进行递归
    return dfs(nums, nums.size()-1, arr, k);
}
int main()
{
    vector<int> nums;
    int k;
    while (1){
        int d;
        int ret = scanf("%d", &d);
        if (ret == EOF){
            break;
        }
        nums.push_back(d);
    }
    k = nums.back();
    nums.pop_back();
    if (canPartitionKSubsets(nums, k)){
        cout << "true";
    }else {
        cout << "false";
    };
    return 0;
}

标签:arr,return,cur,Subsets,nums,int,Sum,vector,限界
From: https://www.cnblogs.com/understanding-friends/p/16776008.html

相关文章

  • 条件区域循环的Sumif
    问题:Sumif条件为D12:D16,求和区域从E3:E8向右,条件区域为B3:D8三列循环函数解决:=SUMIF(OFFSET($B$3:$B$8,,MOD(COLUMN(C1),3)),$D12,E$3:E$8) 思路:利用Mod(Column(......
  • Ele_0008:electron 锁屏恢复事件 resume unlock-screen once事件响应一次
    1,有的时候需要监听Electron的系统恢复事件(从睡眠、休眠中恢复,或者从锁屏状态恢复),这个时候我们会使用Electron主进程powerMonitor模块的resume事件或者unlock-screen事件......
  • CF895C Square Subsets
    CF895CSquareSubsets注意到平方数要求每个质因数的幂次均为偶数。由于\(70\)以内仅有\(19\)个质因数,考虑将每个\(a_i\)按照每个质因数的奇偶性分解为\(01\)串......
  • Subsets of Array
    寻找一组数组中不重复元素的子集packagecom.example.mathematicaldemo.demo;importlombok.extern.slf4j.Slf4j;/***资料:*https://easylearn.baidu.com/edu-......
  • [LeetCode] 1317. Convert Integer to the Sum of Two No-Zero Integers 将整数转换为
    No-Zerointeger isapositiveintegerthat doesnotcontainany 0 initsdecimalrepresentation.Givenaninteger n,return alistoftwointegers [A,......
  • 377.combination-sum-iv 组合总和IV
    问题描述377.组合总和IV解题思路本题依旧是一个完全背包问题,但是本题求的是排列而非组合。参考518.零钱兑换II,先遍历体积,再遍历物品。代码classSolution{public:......
  • ABC267Ex - Odd Sum
    分治NTTEx-OddSum(atcoder.jp)题意给一个长度为\(n\;(1<=n<=10^5)\)的数组\(A\;(A[i]<=10)\),给定\(M\;(1<=M<=10^6)\),求在\(A\)中选奇数个数,满足它们的......
  • ABC 248 C - Dice Sum(DP:背包)
    https://atcoder.jp/contests/abc248/tasks/abc248_c题目大意:给定长度为n,可选择的数字的范围【1,m】,放置的数字的总和不能超过k;问我们能凑出多少种不同的情况?取模。......
  • mybatisplus不支持sum,但支持这个
    我们知道,要对数据求和,写sql很简单:selectsum(exp)fromtable_name我们在用mybatisplus做求和计算的时候,mybatisplus的Wrapper不支持sum函数。这种情况下,我们就无法使用lamb......
  • LeetCode 363. Max Sum of Rectangle No Larger Than K
    原题链接在这里:https://leetcode.com/problems/max-sum-of-rectangle-no-larger-than-k/题目:Givenan mxn matrix matrix andaninteger k,return themaxsum......