|
|
|
@ -10,30 +10,33 @@ public class Code02_SplitSumClosedSizeHalf {
|
|
|
|
|
for (int num : arr) {
|
|
|
|
|
sum += num;
|
|
|
|
|
}
|
|
|
|
|
return process(arr, 0, 0, sum >> 1);
|
|
|
|
|
if ((arr.length & 1) == 0) {
|
|
|
|
|
return process(arr, 0, arr.length / 2, sum / 2);
|
|
|
|
|
} else {
|
|
|
|
|
return Math.max(process(arr, 0, arr.length / 2, sum / 2), process(arr, 0, arr.length / 2 + 1, sum / 2));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// arr[i....]自由选择,挑选的个数一定要是picks个,累加和<=rest, 离rest最近的返回
|
|
|
|
|
public static int process(int[] arr, int i, int picks, int rest) {
|
|
|
|
|
if (i == arr.length) {
|
|
|
|
|
if ((arr.length & 1) == 0) {
|
|
|
|
|
return picks == (arr.length >> 1) ? 0 : -1;
|
|
|
|
|
return picks == 0 ? 0 : -1;
|
|
|
|
|
} else {
|
|
|
|
|
return (picks == (arr.length >> 1) || picks == (arr.length >> 1) + 1) ? 0 : -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
int p1 = process(arr, i + 1, picks, rest);
|
|
|
|
|
// 就是要使用arr[i]这个数
|
|
|
|
|
int p2 = -1;
|
|
|
|
|
int next2 = -1;
|
|
|
|
|
int next = -1;
|
|
|
|
|
if (arr[i] <= rest) {
|
|
|
|
|
next2 = process(arr, i + 1, picks + 1, rest - arr[i]);
|
|
|
|
|
next = process(arr, i + 1, picks - 1, rest - arr[i]);
|
|
|
|
|
}
|
|
|
|
|
if (next2 != -1) {
|
|
|
|
|
p2 = arr[i] + next2;
|
|
|
|
|
if (next != -1) {
|
|
|
|
|
p2 = arr[i] + next;
|
|
|
|
|
}
|
|
|
|
|
return Math.max(p1, p2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static int dp1(int[] arr) {
|
|
|
|
|
public static int dp(int[] arr) {
|
|
|
|
|
if (arr == null || arr.length < 2) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -41,9 +44,9 @@ public class Code02_SplitSumClosedSizeHalf {
|
|
|
|
|
for (int num : arr) {
|
|
|
|
|
sum += num;
|
|
|
|
|
}
|
|
|
|
|
sum >>= 1;
|
|
|
|
|
sum /= 2;
|
|
|
|
|
int N = arr.length;
|
|
|
|
|
int M = (arr.length + 1) >> 1;
|
|
|
|
|
int M = (N + 1) / 2;
|
|
|
|
|
int[][][] dp = new int[N + 1][M + 1][sum + 1];
|
|
|
|
|
for (int i = 0; i <= N; i++) {
|
|
|
|
|
for (int j = 0; j <= M; j++) {
|
|
|
|
@ -52,32 +55,109 @@ public class Code02_SplitSumClosedSizeHalf {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int k = 0; k <= sum; k++) {
|
|
|
|
|
dp[N][M][k] = 0;
|
|
|
|
|
}
|
|
|
|
|
if ((arr.length & 1) != 0) {
|
|
|
|
|
for (int k = 0; k <= sum; k++) {
|
|
|
|
|
dp[N][M - 1][k] = 0;
|
|
|
|
|
}
|
|
|
|
|
for (int rest = 0; rest <= sum; rest++) {
|
|
|
|
|
dp[N][0][rest] = 0;
|
|
|
|
|
}
|
|
|
|
|
for (int i = N - 1; i >= 0; i--) {
|
|
|
|
|
for (int picks = 0; picks <= M; picks++) {
|
|
|
|
|
for (int rest = 0; rest <= sum; rest++) {
|
|
|
|
|
int p1 = dp[i + 1][picks][rest];
|
|
|
|
|
// 就是要使用arr[i]这个数
|
|
|
|
|
int p2 = -1;
|
|
|
|
|
int next2 = -1;
|
|
|
|
|
if (picks + 1 <= M && arr[i] <= rest) {
|
|
|
|
|
next2 = dp[i + 1][picks + 1][rest - arr[i]];
|
|
|
|
|
int next = -1;
|
|
|
|
|
if (picks - 1 >= 0 && arr[i] <= rest) {
|
|
|
|
|
next = dp[i + 1][picks - 1][rest - arr[i]];
|
|
|
|
|
}
|
|
|
|
|
if (next2 != -1) {
|
|
|
|
|
p2 = arr[i] + next2;
|
|
|
|
|
if (next != -1) {
|
|
|
|
|
p2 = arr[i] + next;
|
|
|
|
|
}
|
|
|
|
|
dp[i][picks][rest] = Math.max(p1, p2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return dp[0][0][sum];
|
|
|
|
|
if ((arr.length & 1) == 0) {
|
|
|
|
|
return dp[0][arr.length / 2][sum];
|
|
|
|
|
} else {
|
|
|
|
|
return Math.max(dp[0][arr.length / 2][sum], dp[0][(arr.length / 2) + 1][sum]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// public static int right(int[] arr) {
|
|
|
|
|
// if (arr == null || arr.length < 2) {
|
|
|
|
|
// return 0;
|
|
|
|
|
// }
|
|
|
|
|
// int sum = 0;
|
|
|
|
|
// for (int num : arr) {
|
|
|
|
|
// sum += num;
|
|
|
|
|
// }
|
|
|
|
|
// return process(arr, 0, 0, sum >> 1);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// public static int process(int[] arr, int i, int picks, int rest) {
|
|
|
|
|
// if (i == arr.length) {
|
|
|
|
|
// if ((arr.length & 1) == 0) {
|
|
|
|
|
// return picks == (arr.length >> 1) ? 0 : -1;
|
|
|
|
|
// } else {
|
|
|
|
|
// return (picks == (arr.length >> 1) || picks == (arr.length >> 1) + 1) ? 0 : -1;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// int p1 = process(arr, i + 1, picks, rest);
|
|
|
|
|
// int p2 = -1;
|
|
|
|
|
// int next2 = -1;
|
|
|
|
|
// if (arr[i] <= rest) {
|
|
|
|
|
// next2 = process(arr, i + 1, picks + 1, rest - arr[i]);
|
|
|
|
|
// }
|
|
|
|
|
// if (next2 != -1) {
|
|
|
|
|
// p2 = arr[i] + next2;
|
|
|
|
|
// }
|
|
|
|
|
// return Math.max(p1, p2);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// public static int dp1(int[] arr) {
|
|
|
|
|
// if (arr == null || arr.length < 2) {
|
|
|
|
|
// return 0;
|
|
|
|
|
// }
|
|
|
|
|
// int sum = 0;
|
|
|
|
|
// for (int num : arr) {
|
|
|
|
|
// sum += num;
|
|
|
|
|
// }
|
|
|
|
|
// sum >>= 1;
|
|
|
|
|
// int N = arr.length;
|
|
|
|
|
// int M = (arr.length + 1) >> 1;
|
|
|
|
|
// int[][][] dp = new int[N + 1][M + 1][sum + 1];
|
|
|
|
|
// for (int i = 0; i <= N; i++) {
|
|
|
|
|
// for (int j = 0; j <= M; j++) {
|
|
|
|
|
// for (int k = 0; k <= sum; k++) {
|
|
|
|
|
// dp[i][j][k] = -1;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// for (int k = 0; k <= sum; k++) {
|
|
|
|
|
// dp[N][M][k] = 0;
|
|
|
|
|
// }
|
|
|
|
|
// if ((arr.length & 1) != 0) {
|
|
|
|
|
// for (int k = 0; k <= sum; k++) {
|
|
|
|
|
// dp[N][M - 1][k] = 0;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// for (int i = N - 1; i >= 0; i--) {
|
|
|
|
|
// for (int picks = 0; picks <= M; picks++) {
|
|
|
|
|
// for (int rest = 0; rest <= sum; rest++) {
|
|
|
|
|
// int p1 = dp[i + 1][picks][rest];
|
|
|
|
|
// int p2 = -1;
|
|
|
|
|
// int next2 = -1;
|
|
|
|
|
// if (picks + 1 <= M && arr[i] <= rest) {
|
|
|
|
|
// next2 = dp[i + 1][picks + 1][rest - arr[i]];
|
|
|
|
|
// }
|
|
|
|
|
// if (next2 != -1) {
|
|
|
|
|
// p2 = arr[i] + next2;
|
|
|
|
|
// }
|
|
|
|
|
// dp[i][picks][rest] = Math.max(p1, p2);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// return dp[0][0][sum];
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
public static int dp2(int[] arr) {
|
|
|
|
|
if (arr == null || arr.length < 2) {
|
|
|
|
@ -138,7 +218,7 @@ public class Code02_SplitSumClosedSizeHalf {
|
|
|
|
|
|
|
|
|
|
// for test
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
int maxLen = 20;
|
|
|
|
|
int maxLen = 10;
|
|
|
|
|
int maxValue = 50;
|
|
|
|
|
int testTime = 10000;
|
|
|
|
|
System.out.println("测试开始");
|
|
|
|
@ -146,7 +226,7 @@ public class Code02_SplitSumClosedSizeHalf {
|
|
|
|
|
int len = (int) (Math.random() * maxLen);
|
|
|
|
|
int[] arr = randomArray(len, maxValue);
|
|
|
|
|
int ans1 = right(arr);
|
|
|
|
|
int ans2 = dp1(arr);
|
|
|
|
|
int ans2 = dp(arr);
|
|
|
|
|
int ans3 = dp2(arr);
|
|
|
|
|
if (ans1 != ans2 || ans1 != ans3) {
|
|
|
|
|
printArray(arr);
|
|
|
|
|