1. 程式人生 > 實用技巧 >劃分為k個相等的子集

劃分為k個相等的子集

問題描述 :

給定一個整數陣列 nums 和一個正整數 k,找出是否有可能把這個陣列分成 k 個非空子集,其總和都相等。

示例 1:

輸入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4

輸出: True

說明: 有可能將其分成 4 個子集(5),(1,4),(2,3),(2,3)等於總和。

輸入說明 :

首先輸入nums陣列的長度n,

然後輸入n個整數,以空格分隔。

最後輸入k。

1 <= k <=n<= 16

0 < nums[i] < 10000

輸出說明 :

輸出true或false

輸入範例 :

7
4 3 2 3 5 2 1

4

輸出範例 :

true

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 class Solution {
 4 public:
 5     bool dfs(vector<int>& groups, int index, vector<int>& nums, int target)
 6     {
 7         if (!index)return true;
 8         int val = nums[--index];
 9         for (int
i = 0; i < groups.size(); i++) 10 { 11 if (groups[i] + val <= target) 12 { 13 groups[i] += val; 14 if (dfs(groups, index, nums, target))return true; 15 groups[i] -= val; 16 } 17 if (!groups[i])break
;//每次都保證0值只出現在 group的末尾 18 //例如一個數放在哪個group裡都是一樣的 所以優先放前面的筐 19 } 20 return false; 21 } 22 bool canPartitionKSubsets(vector<int>& nums, int k) { 23 int num_size = nums.size(), sum = 0, target; 24 for (auto i : nums)sum += i; 25 if (sum % k)return false; 26 target = sum / k; 27 sort(nums.begin(), nums.end()); 28 if (nums[num_size - 1] > target)return false; 29 while (num_size && nums[num_size - 1] == target) { num_size--; k--; } 30 if (!num_size)return true; 31 vector<int> group(k, 0);//這裡是大小是k 因為要分成k組 32 return dfs(group, num_size, nums, target); 33 } 34 }; 35 /* 36 7 37 2 2 2 2 3 4 5 38 4 39 */ 40 int main() 41 { 42 int n, data,k; 43 vector<int> vec; 44 cin >> n; 45 for (int i = 0; i < n; i++) 46 { 47 cin >> data; 48 vec.push_back(data); 49 } 50 cin >> k; 51 bool res = Solution().canPartitionKSubsets(vec,k); 52 if (res)cout << "true"; 53 else cout << "false"; 54 return 0; 55 }