题意:给你三个序列,让你取数对,这两个数在不同的序列里。每个数只能取一次,让你求所有数对的两个数的乘积总和最大是多少。
思路:先将三个数组进行从小到大排序,之后dfs 3种取法,每个递归层进行递推。dp[i][j][k]表示用了i个R,j个G,k个B能得到的最大乘积之和。
var readline=require('readline');
var rl=readline.createInterface({
input:process.stdin,
output:process.stdout
});
var arr=[],sol;
function Solve(){
this.val=0;
this.dp=new Array(205);
for(var i=0;i<205;i++){
this.dp[i]=new Array(205);
for(var j=0;j<205;j++) this.dp[i][j]=new Array(205).fill(0);
}
}
Solve.prototype.dfs=function(i,j,k){
if(i<0||j<0||k<0) return 0;
if(this.dp[i][j][k]) return this.dp[i][j][k];
var x=0,y=0,z=0;
x=this.dfs(i-1,j-1,k)+(i>0&&j>0?(this.a[0][i-1]*this.a[1][j-1]):0);
y=this.dfs(i-1,j,k-1)+(i>0&&k>0?(this.a[0][i-1]*this.a[2][k-1]):0);
z=this.dfs(i,j-1,k-1)+(j>0&&k>0?(this.a[1][j-1]*this.a[2][k-1]):0);
return this.val=this.dp[i][j][k]=Math.max(x,Math.max(y,z));
}
Solve.prototype.init=function(){
this.a=new Array(3);
}
rl.on('line',function(inp){
arr.push(inp);
var len=arr.length;
if(len===1){
sol=new Solve();
sol.rgb=arr[0].split(' ');
sol.init();
for(var i=0;i<sol.rgb.length;i++) sol.rgb[i]=parseInt(sol.rgb[i]);
}else{
var b=arr[len-1].split(' ');
for(var i=0;i<sol.rgb[len-2];i++) b[i]=parseInt(b[i]);
sol.a[len-2]=b;
sol.a[len-2].sort(function(x,y){
if(x<y) return -1;
else if(x===y) return 0;
else return 1;
});
}
if(len===4){
sol.dfs(sol.rgb[0],sol.rgb[1],sol.rgb[2]);
console.log(sol.val);
process.exit(0);
}
});