# 平均拆分数组

//注意target就是数组总和的一半:sum/2
//dp[i][j]表示从数组的[0,i]下标范围内选取若干个正整数,达到总和为j的最小总和
public static int func(int[] nums){
int sum = 0;
for(int i:nums) sum+=i;
int target = sum/2;

int[][] dp = new int[nums.length+1][target+1];
for (int i=1;i<=nums.length;i++){
for (int j=1;j<=target;j++){
if (j>=nums[i-1]){//如果大于 就可以进行二选一
dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-nums[i-1]]+nums[i-1]);
}else{
dp[i][j] = dp[i-1][j];
}
}
}
return dp[nums.length][target];
}



public static boolean func2(int[] nums) {
int n = nums.length;
int sum = 0;
for(int i:nums) sum+=i;
int target = sum/2;

boolean[][] dp = new boolean[n + 1][target + 1];
// 如果不选取任何正整数，则被选取的正整数等于 0。因此对于所有 0≤i<n，都有 dp[i][0]=true
for (int i = 0; i <= n; i++) {
dp[i][0] = true;
}

for (int i = 1; i <= n; i++) {
for (int j = 1; j <= target; j++) {
if (j - nums[i - 1] < 0) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j] | dp[i - 1][j - nums[i - 1]];
}
}
}
return dp[n][target];
}


package huatielu;/*
@author Oblak
@date 2022/4/14
@description 可以求得:将一个数组拆分为两个数组使得两个数组的差值最小

*/

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class bag01 {
public static void main(String[] args) {
int[] nums = new int[]{1,3,5,7,5,2,5};
int sum = 0;
HashMap<Integer,Integer> map= new HashMap<>();
for (int i:nums){
sum+=i;
map.put(i,map.getOrDefault(i,0)+1);
}
int ans = func(nums, sum / 2);

boolean[][] booleans = func2(nums, ans);
List<Integer> list = new ArrayList<>();
int target = ans;

//寻找路径 从原来的boolean中先找target位置是否有满足的条件,有的话加入list,然后更新target
int n = nums.length;
while (target>0){
for (int i=1;i<=n;i++){
if (booleans[i][target]){
//System.out.println(nums[i-1]);
target-=nums[i-1];
n=i-1;//之后的n只能从前面的糖果袋中取
break;
}
}
}

for (int i=0;i<list.size();i++){
if (i==0) System.out.print(list.get(0));
else System.out.print(" "+list.get(i));
map.put(list.get(i),map.get(list.get(i))-1);
}
System.out.println();

List<Integer> list2 = new ArrayList<>();
for (int i=0;i<nums.length;i++){
if (map.get(nums[i])>0){
map.put(nums[i],map.get(nums[i])-1);
}
}

for (int i=0;i<list2.size();i++){
if (i==0) System.out.print(list2.get(0));
else System.out.print(" "+list2.get(i));
}

}

public static int func(int[] nums,int target){
int[][] dp = new int[nums.length+1][target+1];

for (int i=1;i<=nums.length;i++){
for (int j=1;j<=target;j++){
if (j>=nums[i-1]){
dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-nums[i-1]]+nums[i-1]);
}else{
dp[i][j] = dp[i-1][j];
}
}

}

for (int i=0;i<dp.length;i++){
System.out.println(Arrays.toString(dp[i]));
}
System.out.println(dp[nums.length][target]);
return dp[nums.length][target];

}

public static boolean[][] func2(int[]nums,int target){
int n = nums.length;
boolean[][] dp = new boolean[n + 1][target + 1];
// 如果不选取任何正整数，则被选取的正整数等于 0。因此对于所有 0≤i<n，都有 dp[i][0]=true
for (int i = 0; i <= n; i++) {
dp[i][0] = true;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= target; j++) {
if (j - nums[i - 1] < 0) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j] | dp[i - 1][j - nums[i - 1]];
}
}
}
for (int i=0;i<dp.length;i++){
System.out.println(Arrays.toString(dp[i]));
}
return dp;
}
}


• 0
点赞
• 0
收藏
• 打赏
• 0
评论
01-09 32
06-04 506
12-08 203
07-10 211
06-01 320
01-15 5005
04-29 795
01-06 2562
11-14 174
11-21 287
11-10 854
03-30 1382
03-06 34
08-01 2248

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

XD流川枫

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。