Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[pull] master from wisdompeak:master #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
pull merged 6 commits into AlgorithmAndLeetCode:master from wisdompeak:master
Jun 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class Solution {
public:
bool canPartitionKSubsets(vector<int>& nums, int k)
{
int n = nums.size();
int sum = accumulate(nums.begin(), nums.end(), 0);
if (sum%k!=0) return false;
int target = sum / k;

vector<int>dp(1<<n, -1);
dp[0] = 0;
for (int state=0; state<(1<<n); state++)
{
if (dp[state]==-1) continue;
for (int i=0; i<n; i++)
{
if (!((state>>i)&1) && (dp[state]+nums[i] <= target))
dp[state + (1<<i)] = (dp[state]+nums[i]) % target;
}
}

return dp[(1<<n)-1] != -1;

}
};
13 changes: 13 additions & 0 deletions DFS/698.Partition-to-K-Equal-Sum-Subsets/Readme.md
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### 698.Partition-to-K-Equal-Sum-Subsets

#### 解法1:搜索
此题据说是NP-hard,没有什么特别高明的算法,就是老老实实地DFS,尝试将所有元素挨个尝试放入k个分类里,直至找到满足条件的分类。

设计如下的递归函数:```DFS(nums, curPos, curGroup, curSum)```.
Expand Down Expand Up @@ -27,5 +28,17 @@ for (int i=curPos; i<n; i++)

与本题非常相似的题目有: 473. Matchsticks to Square, 416. Partition Equal Subset Sum, 996. Number of Squareful Arrays

#### 解法2:状态压缩DP
此题有一种非常巧妙的状压DP的算法。因为本题中nums的个数最多只有16个,那么任意subset的总数不超过2^16=65536,可以用n位的二进制数来表示。另外我们令target=sum/k,表示期望每个subset的元素和。

本题里的dp[state]的定义比较有意思:以state所代表的subset,如果它可以分割成若干个"元素和是target的集合",再加上若干个总和不超过target的元素零头,那么dp[state]就表示为subset的元素总和对于target的取余(也就是所说的零头);否则dp[state]设为-1.

举个例子,如果state代表的是{1,2,3,4},target是4,那么因为这个state可以分割成{4},{1+3},{2},所以dp[state]=2. 为什么这么定义dp呢?这是因为,如果当前dp[state]的值不是-1,那么我们只需要关心的今后是否能有新的元素可以补足目前的零头凑成另一个target。以这个例子来说,如果再来一个新元素是1加入目前的subset,新元素1和旧元素2放入待定区,那么可以就得到dp[state2]=3;同理,如果再来一个新元素是2加入目前的subset,新元素2和旧元素2恰好凑成一组target的集合,于是dp[state2]=0;但是如果再来一个新元素是3,已有的零头2加上3就超过了target,说明新来的3无法与目前的零头凑成一组target的集合,所以我们就放弃dp[state2]的更新。

所以我们本题状态转移的思想是,根据当前的state,考察可以加入哪些新元素(比如说i)得到新的state2,使得```dp[state]+nums[i]<=target```。满足的话,那么就可以更新dp[state2]为该组合的元素之和对于target的取余(零头)。

最终的答案就是考察state=(1<<n)-1时的dp值是否不为-1. (其实,如果dp值不为-1的话,它一定是0,因为我们预判了所有元素之和必然要被target整除)

该解法的时间复杂度是```2^n*n```.

[Leetcode Link](https://leetcode.com/problems/partition-to-k-equal-sum-subsets)

AltStyle によって変換されたページ (->オリジナル) /