Description:
Given an array of integers nums
and a positive integer k
, find whether it's possible to divide this array into k
non-empty subsets whose sums are all equal.
Example 1:
Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4 Output: True Explanation: It's possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums.
Note:
1 <= k <= len(nums) <= 16
.0 < nums[i] < 10000
.
Thought:
本题虽然在动态规划的范围内,但是并没有发现特别好的利用动态规划的解法。
如果sum/k不能整除,或者nums中存在任意比k大的数,则无解。
接着nums中的每个元素对应k个状态,所有有 nk 中情况,dfs用到了剪枝,排序贪心尽早把不合法的解从递归树中删除。
Code:
class Solution { public: bool canPartitionKSubsets(vector<int>& nums, int k) { int max = 0; int sum = 0; for (int i = 0; i < nums.size(); i++) { sum += nums[i]; max = max < nums[i] ? nums[i] : max; } if (sum%k != 0)return false; if (max > sum / k)return false; vector<int> memo(k, 0); return search(nums, 0,nums.size(),k,sum/k,memo); }
bool search(vector<int>& nums, int pos, int n, int k, int target, vector<int>& memo) { if (pos == n) return true; // n, int jEnd = std::min(k, pos + 1); for (int j = 0; j < jEnd; ++j) { if (nums[pos] + memo[j] > target) { continue; } memo[j] += nums[pos]; if (search(nums, pos + 1, n, k, target, memo)) { return true; } memo[j] -= nums[pos]; } return false; } };