程序员代码面试指南刷题--第四章.打气球的最大分数

题目描述
给定一个数组arr,长度为n。代表排有分数的气球。 每打爆一个气球都能获得分数,假设打爆气球的分数为X,获得分数的规则如下:
1)如果被打爆气球的左边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为L:如果被打爆气球的右边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为R.获得分数为LXR
2)如果被打爆的气球的左边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为L:如果被打爆气球的右边所有气球都已经被打爆,获得分数为LX。
3)如果被打爆气球的左边所有的气球都已经被打爆:如果被打爆气球的右边有没被打爆的气球,找到离被打爆气球最近的气球。获得分数为X
R.
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));
    }
}

你可能感兴趣的:(程序员代码面试指南刷题)