1. 程式人生 > >最強戰隊

最強戰隊

每個同學都有一個能力值, 從N個同學中選出S個同學,要求選出的同學的能力值的乘積最大,且要求被選出的相鄰兩個同學的編號的差不超過D。

動態規劃

public class BestTeam {
    public Long getBestTeam(int numbers, int[] abilities, int selectedNum, int distance){
     
        long[][] fmax = new long[selectedNum+1][numbers+1];
       
        long[][] fmin = new long[selectedNum+1][numbers+1];

        /**
         *  fmax[k][i]表示 : 當選中了k個學生,並且以第i個學生為結尾,所產生的最大乘積;
         *  fmin[k][i]表示 : 當選中了k個學生,並且以第i個學生為結尾,所產生的最小乘積;
         */

        //初始化第一行
        long  res = Integer.MIN_VALUE; // 記得用Long型別,考慮數值範圍
        for (int i = 1; i <=numbers; i++) {
            fmax[1][i] = abilities[i];
            fmin[1][i] = abilities[i];
            for (int k = 2; k <=selectedNum; k++) {
                for (int j = i-1 ; j > 0 &&  i-j<=distance ; j--) {
                    fmax[k][i] = Math.max(fmax[k][i], Math.max(fmax[k-1][j] * abilities[i], fmin[k-1][j] * abilities[i]));
                    fmin[k][i] = Math.min(fmin[k][i], Math.min(fmax[k-1][j] * abilities[i], fmin[k-1][j] * abilities[i]));
                }
            }
            res = Math.max(res ,fmax[selectedNum][i]);
        }
        return res;
    }
}