AcWing 282. 【Java】石子合并
原题链接
简单
作者:
tt2767
,
2020-01-15 00:53:00
,
所有人可见
,
阅读 1023
/*
1. 状态定义: f[i][j] 表示合并区间[i~j]花费的最小体力
2. 状态计算: f[i][j] 必定为f[i][k], f[k+1][r]两堆合并而来,而合并两堆的代价必定是 a[i]+a[i+1]+....+ a[j]
f[i][j] = MIN(f[i][k] + f[k+1][r]) + S[R] - S[L-1]
3. 边界: f[~][~] = INF, f[i][i] = 0
4. 循环从外到内:阶段-状态-决策
*/
import java.util.*;
public class Main{
void run(){
int n = jin.nextInt();
for (int i = 1 ; i <= n ; i++) {
a[i] = jin.nextInt();
preSum[i] = preSum[i-1] + a[i];
}
int res = dp(n);
System.out.println(res);
}
int dp(int n){
for (int i = 1 ; i <= n ; i++){
for (int j = 1; j <= n ; j++){
f[i][j] = i == j ? 0 : Integer.MAX_VALUE;
}
}
for (int l = 2; l <= n ; l++){
for (int i = 1; i + l - 1 <= n; i++){
int j = i + l - 1;
for (int k = i; k <= j-1 ; k++){
f[i][j] = Math.min(f[i][j], f[i][k] + f[k+1][j] + preSum[j] - preSum[i-1]);
}
}
}
return f[1][n];
}
int maxN = 302;
int[] a = new int[maxN];
int[] preSum = new int[maxN];
int[][] f = new int[maxN][maxN];
Scanner jin = new Scanner(System.in);
public static void main(String[] args) {new Main().run();}
}