タイトル説明:
射撃場にはN個のターゲットがあり、各ターゲットにはスコアがあり、スコア配列に保存されます。i番目のターゲットをヒットするためのスコアはscore [left] * score [i] * score [right]であり、元の左右のターゲットが隣接するターゲットになります。スコア0のターゲットは撃たれません。左が存在しないか撃たれない場合、スコアはスコア[i] *スコア[右]です。同様に、右もこのルールに従います。左と右が存在しない場合、または撮影できない場合、スコアはscore [i]です。撃つことができるすべてのターゲットをヒットするために獲得できるポイント数を計算してください。設計アルゴリズム。
説明を入力してください:
ターゲットの数n各ターゲットのスコア
出力:すべてのターゲットをヒットするためのスコア
入力例:
4
2
3
0
3
出力例:
12
コード:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int arr[] = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt();
}
in.close();
System.out.println(getScore(arr, 0, n - 1));
}
public static int getScore(int[] score, int start, int end) {
if (score == null || start > end) {
return 0;
}
int n = end - start + 1;
for (int i = start; i < end; i++) {
if (score[i] == 0) {
return getScore(score, start, i - 1)
+ getScore(score, i + 1, end);
}
}
// 将score数组移到新的数组,在前后分别加一个值为1的数
int[] arr = new int[n + 2];
for (int i = start + 1; i <= end + 1; i++) {
arr[i - start] = score[i - 1];
}
arr[0] = arr[n + 1] = 1;
int[][] dp = new int[n + 2][n + 2];
int m = n + 2;
for (int k = 2; k < m; k++) {// 左右下标差,k=2表示left和right中间隔1个
for (int left = 0; left < m - k; ++left) {
int right = left + k;
for (int i = left + 1; i < right; ++i) {// 击中第i个靶
dp[left][right] = Math.max(dp[left][right], arr[left]
* arr[i] * arr[right] + dp[left][i] + dp[i][right]);
// 表示最后一个击中的是i号靶时的最大成绩
// left right中间的分数等于 最后剩i号靶时 i号靶分数是arr[left]* arr[i] *
// arr[right]
// left 到 i 号靶之间分数是dp[left][i] i到right之间分数是dp[i][right]
// 把所有i遍历一遍取最大值
}
}
}
return dp[0][m - 1];
}
}
参照ブログ: Leetcode312。バーストバルーン分析