1. 程式人生 > >動態規劃 java 石子問題(直線)

動態規劃 java 石子問題(直線)

一.石子問題與動態規劃的矩陣相乘問題類似,剛開始我在陣列邊界上出現了小問題,讓我知道了,陣列的邊界一定到精確,<還是<=,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;
}

那麼中文中27行的sum[j - 1]- sum[i - 1] + a[i - 1];就可以改為getSum(a, i - 1, j - 1);無疑是方便很多,

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]); } } }