You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
2.7 KiB

package class42;
import java.util.Arrays;
public class Code01_PostOfficeProblem {
public static int min1(int[] arr, int num) {
if (arr == null || num < 1 || arr.length < num) {
return 0;
}
int N = arr.length;
int[][] w = new int[N + 1][N + 1];
for (int L = 0; L < N; L++) {
for (int R = L + 1; R < N; R++) {
w[L][R] = w[L][R - 1] + arr[R] - arr[(L + R) >> 1];
}
}
int[][] dp = new int[N][num + 1];
for (int i = 0; i < N; i++) {
dp[i][1] = w[0][i];
}
for (int i = 1; i < N; i++) {
for (int j = 2; j <= Math.min(i, num); j++) {
int ans = Integer.MAX_VALUE;
for (int k = 0; k <= i; k++) {
ans = Math.min(ans, dp[k][j - 1] + w[k + 1][i]);
}
dp[i][j] = ans;
}
}
return dp[N - 1][num];
}
public static int min2(int[] arr, int num) {
if (arr == null || num < 1 || arr.length < num) {
return 0;
}
int N = arr.length;
int[][] w = new int[N + 1][N + 1];
for (int L = 0; L < N; L++) {
for (int R = L + 1; R < N; R++) {
w[L][R] = w[L][R - 1] + arr[R] - arr[(L + R) >> 1];
}
}
int[][] dp = new int[N][num + 1];
int[][] best = new int[N][num + 1];
for (int i = 0; i < N; i++) {
dp[i][1] = w[0][i];
best[i][1] = -1;
}
for (int j = 2; j <= num; j++) {
for (int i = N - 1; i >= j; i--) {
int down = best[i][j - 1];
int up = i == N - 1 ? N - 1 : best[i + 1][j];
int ans = Integer.MAX_VALUE;
int bestChoose = -1;
for (int leftEnd = down; leftEnd <= up; leftEnd++) {
int leftCost = leftEnd == -1 ? 0 : dp[leftEnd][j - 1];
int rightCost = leftEnd == i ? 0 : w[leftEnd + 1][i];
int cur = leftCost + rightCost;
if (cur <= ans) {
ans = cur;
bestChoose = leftEnd;
}
}
dp[i][j] = ans;
best[i][j] = bestChoose;
}
}
return dp[N - 1][num];
}
// for test
public static int[] randomSortedArray(int len, int range) {
int[] arr = new int[len];
for (int i = 0; i != len; i++) {
arr[i] = (int) (Math.random() * range);
}
Arrays.sort(arr);
return arr;
}
// for test
public static void printArray(int[] arr) {
for (int i = 0; i != arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// for test
public static void main(String[] args) {
int N = 30;
int maxValue = 100;
int testTime = 10000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int len = (int) (Math.random() * N) + 1;
int[] arr = randomSortedArray(len, maxValue);
int num = (int) (Math.random() * N) + 1;
int ans1 = min1(arr, num);
int ans2 = min2(arr, num);
if (ans1 != ans2) {
printArray(arr);
System.out.println(num);
System.out.println(ans1);
System.out.println(ans2);
System.out.println("Oops!");
}
}
System.out.println("测试结束");
}
}