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

Commit 19abe18

Browse files
添加 0416.分割等和子集.md C语言版本
1 parent d15c4af commit 19abe18

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

‎problems/0416.分割等和子集.md‎

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,106 @@ var canPartition = function(nums) {
416416
};
417417
```
418418

419+
C:
420+
二维dp:
421+
```c
422+
/**
423+
1. dp数组含义:dp[i][j]为背包重量为j时,从[0-i]元素和最大值
424+
2. 递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i])
425+
3. 初始化:dp[i][0]初始化为0。因为背包重量为0时,不可能放入元素。dp[0][j] = nums[0],当j >= nums[0] && j < target时
426+
4. 遍历顺序:先遍历物品,再遍历背包
427+
*/
428+
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
429+
430+
int getSum(int* nums, int numsSize) {
431+
int sum = 0;
432+
433+
int i;
434+
for(i = 0; i < numsSize; ++i) {
435+
sum += nums[i];
436+
}
437+
return sum;
438+
}
439+
440+
bool canPartition(int* nums, int numsSize){
441+
// 求出元素总和
442+
int sum = getSum(nums, numsSize);
443+
// 若元素总和为奇数,则不可能得到两个和相等的子数组
444+
if(sum % 2)
445+
return false;
446+
447+
// 若子数组的和等于target,则nums可以被分割
448+
int target = sum / 2;
449+
// 初始化dp数组
450+
int dp[numsSize][target + 1];
451+
// dp[j][0]都应被设置为0。因为当背包重量为0时,不可放入元素
452+
memset(dp, 0, sizeof(int) * numsSize * (target + 1));
453+
454+
int i, j;
455+
// 当背包重量j大于nums[0]时,可以在dp[0][j]中放入元素nums[0]
456+
for(j = nums[0]; j <= target; ++j) {
457+
dp[0][j] = nums[0];
458+
}
459+
460+
for(i = 1; i < numsSize; ++i) {
461+
for(j = 1; j <= target; ++j) {
462+
// 若当前背包重量j小于nums[i],则其值等于只考虑0到i-1物品时的值
463+
if(j < nums[i])
464+
dp[i][j] = dp[i - 1][j];
465+
// 否则,背包重量等于在背包中放入num[i]/不放入nums[i]的较大值
466+
else
467+
dp[i][j] = MAX(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i]);
468+
}
469+
}
470+
// 判断背包重量为target,且考虑到所有物品时,放入的元素和是否等于target
471+
return dp[numsSize - 1][target] == target;
472+
}
473+
```
474+
滚动数组:
475+
```c
476+
/**
477+
1. dp数组含义:dp[j]为背包重量为j时,其中可放入元素的最大值
478+
2. 递推公式:dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
479+
3. 初始化:均初始化为0即可
480+
4. 遍历顺序:先遍历物品,再后序遍历背包
481+
*/
482+
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
483+
484+
int getSum(int* nums, int numsSize) {
485+
int sum = 0;
486+
487+
int i;
488+
for(i = 0; i < numsSize; ++i) {
489+
sum += nums[i];
490+
}
491+
return sum;
492+
}
493+
494+
bool canPartition(int* nums, int numsSize){
495+
// 求出元素总和
496+
int sum = getSum(nums, numsSize);
497+
// 若元素总和为奇数,则不可能得到两个和相等的子数组
498+
if(sum % 2)
499+
return false;
500+
// 背包容量
501+
int target = sum / 2;
502+
503+
// 初始化dp数组,元素均为0
504+
int dp[target + 1];
505+
memset(dp, 0, sizeof(int) * (target + 1));
506+
507+
int i, j;
508+
// 先遍历物品,后遍历背包
509+
for(i = 0; i < numsSize; ++i) {
510+
for(j = target; j >= nums[i]; --j) {
511+
dp[j] = MAX(dp[j], dp[j - nums[i]] + nums[i]);
512+
}
513+
}
514+
515+
// 查看背包容量为target时,元素总和是否等于target
516+
return dp[target] == target;
517+
}
518+
```
419519

420520

421521

0 commit comments

Comments
(0)

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