小q和博士在玩一个石子合并的游戏。初始一共有n堆石子,每堆石子有w[i]个石子。小q和博士他们需要对识字进行合并,每次他们可以选任意2堆石子合并。一堆有x个石子和一堆有y个石子的石子堆合并得到一堆有x+y个石子的石子堆,这次合并得分为x*y,只剩下一堆石子时游戏结束。小牛和博士希望采取优秀的策略获得最大得分,请算他们的最大得分是多少?
输入:一个正整数
n个正整数,即每堆石子的个数
输出:最大得分
例:输入:3
1,2,3
输出:11
没想到好办法,只会这个笨办法
function getMax(ary,temp){
var temp=temp||0;
if(ary.length<2){
return temp;
}
if(ary.length==2){
temp+=ary[0]*ary[1]
return temp;
}
var tempAry=[];
for(var i=0;i<ary.length-1;i++){
for(var j=i+1;j<ary.length;j++){
var newAry=ary.filter(function(item,index){
return index!=i&&index!=j;
});
newAry.push(ary[i]+ary[j]);
tempAry.push(getMax(newAry,temp+ary[i]*ary[j]))
}
}
return Math.max.apply(null,tempAry);
}
console.log(getMax([7,58,9,10,27,28]))
这题是个陷阱啊,考的是数学知识,不管选取的顺序是什么,最终的结果是不变的
公式是:
( (n[1]+n[2]+n[3]+..+n[m])(n[1]+n[2]+n[3]+..+n[m])-(n[1]n[1]+n[2]n[2]+...n[m]n[m]) )/2
防止计算过程中整数溢出:
function getValue(ary){
var addValue=0;
var resultValue=0;
for(var i=0;i<ary.length;i++){
addValue+=ary[i];
}
for(var i=0;i<ary.length;i++){
resultValue+=addValue*ary[i];
resultValue-=ary[i]*ary[i];
}
return resultValue/2;
}