codeforces educational round 93 D

题意:给你三个序列,让你取数对,这两个数在不同的序列里。每个数只能取一次,让你求所有数对的两个数的乘积总和最大是多少。
思路:先将三个数组进行从小到大排序,之后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);
    }
});

猜你喜欢

转载自blog.csdn.net/weixin_43916777/article/details/108022613