動態規劃 java 石子問題(直線)
阿新 • • 發佈:2019-01-30
一.石子問題與動態規劃的矩陣相乘問題類似,剛開始我在陣列邊界上出現了小問題,讓我知道了,陣列的邊界一定到精確,<還是<=,n還是n+1,都要精益求精;
二 .還有就是在i到j石子之和處出現問題,1.sum[j]-sum[i-1]
2.sum[j]-sum[i-2] 3.sum[j]-sum[i-1]+a[i-1]第一種會遺失a[i-1]的值,第二種會出現陣列越界異常,所以第三種才是正確的,
3.關於第二個問題,我看到了某神是這樣寫的
public static int getSum(int[] a2, int a, int b) {
int sum = 0;
for(int i = a;i <= b;i++)
sum += a2[i];
return sum;
}
package my;
import java.util.Scanner;
/*在一條直線上有n堆石子,每堆有一定的數量,每次可以將兩堆相鄰的石子合併,
* 合併後放在兩堆的中間位置,合併的費用為兩堆石子的總數。
* 求把所有石子合併成一堆的最小花費。*/
public class shiziwenti {
public static void main(String[] args) {
int n = new Scanner(System.in).nextInt();
int[] a = new int[n];
int[] sum = new int[n];
int[][] dp = new int[n + 1][n + 1];
getsum(a, sum, n);
printresult(dp, sum, a, n);
System.out.print("\t" + dp[1][n]);
}
//計算最短花費
private static void printresult(int[][] dp, int [] sum, int[] a, int n) {
for (int len = 2; len <= n; len++) {
for (int i = 1; i <= n - len + 1; i++) {
int j = i + len - 1;
dp[i][j] = Integer.MAX_VALUE;
for (int k = i; k < j; k++) {
int temp = dp[i][k] + dp[k + 1][j] + sum[j - 1]
- sum[i - 1] + a[i - 1];
if (temp < dp[i][j])
dp[i][j] = temp;
}
}
}
}
//計算石子的和
private static void getsum(int[] a, int[] sum, int n) {
for (int i = 0; i < n; i++)
a[i] = new Scanner(System.in).nextInt();
if (n == 1)
System.out.print(a[0]);
else {
sum[0] = a[0];
for (int i = 1; i < n; i++)
sum[i] = sum[i - 1] + a[i];
for (int i = 0; i < n; i++)
System.out.print(sum[i]);
}
}
}