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

本文介绍了一个使用C++编写的算法,通过暴力遍历和剪枝策略,解决将一组整数分成K个子集,使得每个子集的和相等的问题。文章详细解释了函数实现和条件判断过程。

这将会是一个系统性的算法学习专栏,编程语言为C++,适用于刚开始学算法的学生和博友,建议需要的朋友收藏订阅,是免费的,希望对大家能够有所帮助。

在这里插入图片描述

纯暴力遍历+剪枝,将任务看出有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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值