在C ++中对K个相等和子集的分区
假设我们有一个称为nums的整数数组和一个正整数k,请检查是否有可能将此数组划分为总和相同的k个非空子集。因此,如果数组类似于[4,3,2,3,5,2,1]且k=4,则结果将为True,因为给定的数组可以分为四个子数组,例如[[5],[1,4],[2,3],[2,3]]的总和相等。
为了解决这个问题,我们将遵循以下步骤-
定义两个称为dp的表,其总大小为2^n,
对给定的数组num进行排序,设置sum:=nums数组中所有元素的总和
如果summodk非0或nums的最后一个元素>sum/k,则返回false
设置dp[0]:=true和sum:=sum/k
对于0到2^n的i
对于j,范围为0至,
如果nums[j]<=sum–total[i]modsum,则dp[temp]:=true
总数[temp]:=总数[i]+数字[j]
温度:=iOR2^j
如果temp与我不同,则
否则从循环中出来
如果dp[i]不为零,则
返回dp[(2^n)-1]
例子(C++)
让我们看下面的实现以更好地理解-
#include <bits/stdc++.h> using namespace std; class Solution { public: bool canPartitionKSubsets(vector<int>& nums, int k) { int n = nums.size(); vector <bool> dp(1 << n); vector <int> total(1 << n); sort(nums.begin(), nums.end()); int sum = 0; for(int i = 0; i < nums.size(); i++)sum += nums[i]; if(sum % k || nums[nums.size() - 1] > sum / k) return false; dp[0] = true; sum /= k; for(int i = 0; i < (1 << n); i++){ if(dp[i]){ for(int j = 0; j < n; j++){ int temp = i | (1 << j); if(temp != i){ if(nums[j] <= sum - (total[i] % sum)){ dp[temp] = true; total[temp] = total[i] + nums[j]; } else{ break; } } } } } return dp[(1 << n) - 1]; } }; main(){ Solution ob; vector<int> v = {4,3,2,3,5,2,1}; cout << (ob.canPartitionKSubsets(v, 4)); }
输入值
[4,3,2,3,5,2,1] 4
输出结果
1