题目描述
给定一个数组arr,长度为n。代表排有分数的气球。 每打爆一个气球都能获得分数,假设打爆气球的分数为X,获得分数的规则如下:
1)如果被打爆气球的左边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为L:如果被打爆气球的右边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为R.获得分数为LXR
2)如果被打爆的气球的左边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为L:如果被打爆气球的右边所有气球都已经被打爆,获得分数为LX。
3)如果被打爆气球的左边所有的气球都已经被打爆:如果被打爆气球的右边有没被打爆的气球,找到离被打爆气球最近的气球。获得分数为XR.
4)如果被打爆气球的左边和右边所有的气球都已经被打爆。获得分数为X。
目标是打爆所有气球,获得每次打爆的分数。通过选择打爆气球的顺序,可以得到不同的总分,请返回能获得的最大分数。
输入描述:
输出包括两行,第一行包括一个整数n(0<=n<=500),第二行包括n个整数,代表数组arr (1<=arr[i]<=100)。
输出描述:
输出包括一个整数,代表可能获得的最大分数。
示例1
输入
3
3 2 5
输出
50
解法一:暴力递归
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(br.readLine());
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<arr.length;i++){
arr[i] = Integer.parseInt(ss[i]);
}
int res = findMax(arr);
System.out.println(res);
}
public static int findMax(int[] arr){
if(arr==null||arr.length==0) return 0;
if(arr.length==1) return arr[0];
int[] help = new int[arr.length+2];
help[0] = 1;
help[help.length-1] = 1;
for(int i=1;i<help.length-1;i++){
help[i] = arr[i-1];
}
return process(help,1,help.length-2);
}
public static int process(int[] arr,int l,int r){
if(l==r) return arr[l]*arr[l-1]*arr[r+1];
int max = 0;
max = Math.max(process(arr,l+1,r)+arr[l]*arr[l-1]*arr[r+1],process(arr,l,r-1)+arr[r]*arr[r+1]*arr[l-1]);
for(int i=l+1;i<r;i++){
max = Math.max(max,process(arr,l,i-1)+process(arr,i+1,r)+arr[i]*arr[l-1]*arr[r-1]);
}
return max;
}
}
解法二:动态规划
问题:数组越界非法访问?
麻辣皮:注意加上
if (len == 0) {
System.out.println(0);
return;
}
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(br.readLine());
//加在这里
if (len == 0) {
System.out.println(0);
return;
}
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<arr.length;i++){
arr[i] = Integer.parseInt(ss[i]);
}
int res = findMax1(arr);
System.out.println(res);
}
public static int findMax(int[] arr){
if(arr==null||arr.length==0) return 0;
if(arr.length==1) return arr[0];
int N = arr.length;
int[] help = new int[N+2];
help[0] = 1;
help[N+1] = 1;
for(int i=0;i<N;i++){
help[i+1] = arr[i];
}
int[][] dp = new int[N+2][N+2];
for(int i=1;i<=N;i++){
dp[i][i] = help[i-1]*help[i]*help[i+1];
}
for(int l = N;l>=1;l--){
for(int r=l+1;r<=N;r++){
int finaL = help[l-1]*help[l]*help[r+1]+dp[l+1][r];
int finaR = help[l-1]*help[r]*help[r+1]+dp[l][r-1];
dp[l][r] = Math.max(finaL,finaR);
for(int i=l;i<r;i++){
dp[l][r] = Math.max(dp[l][r],help[l-1]*help[i]*help[r+1]+dp[l][i-1]+dp[i+1][r]);
}
}
}
return dp[1][N];
}
public static int findMax1(int[] arr){
if(arr==null||arr.length==0) return 0;
if(arr.length==1) return arr[0];
int[] help = new int[arr.length+2];
help[0] = 1;
help[help.length-1] = 1;
for(int i=1;i<help.length-1;i++){
help[i] = arr[i-1];
}
int[][] dp = new int[help.length][help.length];
//处理对角线
for(int i=1;i<help.length-1;i++){
dp[i][i] = help[i]*help[i-1]*help[i+1];
}
for(int l=help.length-2;l>=1;l--){
for(int r=l+1;r<=help.length-2;r++){
int max = Math.max(dp[l+1][r]+help[l]*help[l-1]*help[r+1],dp[l][r-1]+help[r]*help[r+1]*help[l-1]);
for(int i=l+1;i<r;i++){
max = Math.max(max,dp[l][i-1]+dp[i+1][r]+help[i]*help[l-1]*help[r+1]);
}
dp[l][r] = max;
}
}
return dp[1][arr.length];
}
}
解法三:动态规划二
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main{
public static int maxCores2(int[] cores) {
int len = cores.length;
int[][] dp = new int[len][len];
for (int i = 0; i < len; i++)
for (int j = i - 2; j >= 0; j--)
for (int k = j + 1; k < i; k++)
dp[i][j] = Math.max(dp[i][j],
dp[k][j] + dp[i][k] + cores[i] * cores[j] * cores[k]);
return dp[len - 1][0];
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] strs = br.readLine().split(" ");
int n = Integer.parseInt(strs[0]);
if (n == 0) {
System.out.println(0);
return;
}
strs = br.readLine().split(" ");
int[] cores = new int[n + 2];
cores[0] = cores[n + 1] = 1;
for (int i = 1; i < cores.length - 1; i++)
cores[i] = Integer.parseInt(strs[i - 1]);
System.out.println(maxCores2(cores));
}
}