现有司机N人,调度中心会将所有司机平分给A、B两个区域
第i个司机去A可得收入为income[i][0],
第i个司机去B可得收入为income[i][1],
返回所有调度方案中能使所有司机总收入最高的方案,是多少钱
package 题目.Code_02;
//现有司机N人,调度中心会将所有司机平分给A、B两个区域
//第i个司机去A可得收入为income[i][0],
//第i个司机去B可得收入为income[i][1],
//返回所有调度方案中能使所有司机总收入最高的方案,是多少钱
public class Drive {
//income -> N * 2的矩阵
// A B
// 0: [1 , 2]
// 1: [2 , 3]
public static int maxMoney1(int[][] income){
if(income == null || income.length<2 || (income.length & 1) != 0){
return 0;
}
int N = income.length;//去A区 N/2 B区 N/2
int M = N>>1;//去A区的人数
return process(income,0,M);
}
public static int process(int[][] income,int index,int rest){
if(index==income.length){
return 0;
}
//去b区的人满了,剩下的只能去a区
if(income.length-index==rest){
return income[index][0]+process(income,index+1,rest-1);
}
//去a区的人满了,剩下的只能去b区
if(rest==0){
return income[index][1]+process(income,index+1,rest);
}
//当前司机 选择去a区还是去b区
int ARes=income[index][0] + process(income, index + 1, rest - 1);
int BRes = income[index][1]+process(income,index+1,rest);
return Math.max(ARes,BRes);
}
//自己手撸的dp,可参考一下
public static int maxMoney2(int[][] income){
if(income == null || income.length<2 || (income.length & 1) != 0){
return 0;
}
int N = income.length;
int M = N>>1;
int[][] dp = new int[N+1][M+1];
//去b区的人满了,剩下的只能去a区
for(int i=1;i<=M;i++){
dp[N-i][i]=income[N-i][0]+dp[N-i+1][i-1];
}
//去a区的人满了,剩下的只能去b区
for(int index=N-1;index>=0;index--){
dp[index][0]= income[index][1]+ dp[index+1][0];
}
for(int index=N-1;index>=0;index--){
for(int rest=M;rest>0;rest--){
if(dp[index][rest]==0){
//当前司机 选择去a区还是去b区
int p1 = income[index][0]+dp[index+1][rest-1];
int p2 = income[index][1]+dp[index+1][rest];
dp[index][rest]=Math.max(p1,p2);
}
}
}
//return process(income,0,M);
return dp[0][M];
}
public static void main(String[] args){
int[][] income={{1,2},{6,4},{5,1},{7,8},{9,1},{10,10}};
System.out.println(maxMoney1(income));
System.out.println(maxMoney2(income));
}
}