不记得在什么地方看到的一个题目:
两个数组:A,B,各存放一系列数据
对AB中的元素进行一系列的交换,以使得两数组元素和:Sum(A),Sum(B) 之差最小。
我的想法是,如果从A、B中找出一些数,使得他们的和最接近Sum(A)+Sum(B)的一半,那么把这些数放在A中,另外的放在B中,结果是否就可以了呢。
于是我又如下的实现;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript">
var selected ;
var selected2;
function change(){
var nums1 = document.getElementById("numGroup1").value;
var nums2 = document.getElementById("numGroup2").value;
var array1 = nums1.split(',');
var array2 = nums2.split(',');
var newa=array1.concat(array2);
var sum = 0;
for(var i=0;i<newa.length;i++){
newa[i] = parseInt(newa[i]);
sum+=newa[i];
newa[i]*=2;
}
selected = new Array(newa.length);
selected2 = new Array(newa.length);
alert(sum+","+newa);
var v = f(sum,newa,0);
//alert("result="+selected);
alert(sum+",min dist="+v);
array1.length=0;
array2.length=0;
for(var i=0;i<newa.length;i++){
if(selected[i]==0)
array1.push(newa[i]/2);
else
array2.push(newa[i]/2);
}
document.getElementById("numGroup1_0").value = array1.join(',');
document.getElementById("numGroup2_0").value = array2.join(',');
}
var selThis = false;
//return the the dist between sum and part-sum of the array
//select among the nums after i
//make them closest to half of sum
var cDist = 1000;
function f( sum,allNums, i){
if(i==allNums.length){
var x = sum;
alert(0+"|"+selected2+"|"+cDist+","+x);
if(Math.abs(cDist)>Math.abs(x)){
cp();
cDist = x;
}
return sum;
}
if( i<allNums.length){
selected2[i]=true;
var dist1 = f(sum, allNums,i+1);
selected2[i] = false;
var dist2 = f(sum-allNums[i], allNums,i+1);
selThis = (Math.abs(dist1)>Math.abs(dist2));
if( selThis)
return dist2;
else
return dist1;
}
}
function absDis(n1,n2){
return Math.abs(n1-n2);
}
function cp( ){
selected.length=0;
for(var i=0;i<selected2.length;i++){
//selected.push(selected2[i]);
selected[i]=selected2[i];
}
}
</script>
</head>
<body>
<input id="numGroup1" type="text" size="20" value="1,2,3,4,5" />
<br>
<input id="numGroup2" type="text" size="20" value="9,-1,4,2" />
<br>
<input type="button" value="change" οnclick="change();" />
<br>
<input id="numGroup1_0" type="text" size="20" value="" />
<br>
<input id="numGroup2_0" type="text" size="20" value="" />
<br>
</body>
</html>
当然这里的实现使用的是简单遍历的方法,最坏情况下时间复杂度是2^n, 不过这只是第一版本,我会继续改进,也希望各位高手多多指点。
:-)
两个数组:A,B,各存放一系列数据
对AB中的元素进行一系列的交换,以使得两数组元素和:Sum(A),Sum(B) 之差最小。
我的想法是,如果从A、B中找出一些数,使得他们的和最接近Sum(A)+Sum(B)的一半,那么把这些数放在A中,另外的放在B中,结果是否就可以了呢。
于是我又如下的实现;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript">
var selected ;
var selected2;
function change(){
var nums1 = document.getElementById("numGroup1").value;
var nums2 = document.getElementById("numGroup2").value;
var array1 = nums1.split(',');
var array2 = nums2.split(',');
var newa=array1.concat(array2);
var sum = 0;
for(var i=0;i<newa.length;i++){
newa[i] = parseInt(newa[i]);
sum+=newa[i];
newa[i]*=2;
}
selected = new Array(newa.length);
selected2 = new Array(newa.length);
alert(sum+","+newa);
var v = f(sum,newa,0);
//alert("result="+selected);
alert(sum+",min dist="+v);
array1.length=0;
array2.length=0;
for(var i=0;i<newa.length;i++){
if(selected[i]==0)
array1.push(newa[i]/2);
else
array2.push(newa[i]/2);
}
document.getElementById("numGroup1_0").value = array1.join(',');
document.getElementById("numGroup2_0").value = array2.join(',');
}
var selThis = false;
//return the the dist between sum and part-sum of the array
//select among the nums after i
//make them closest to half of sum
var cDist = 1000;
function f( sum,allNums, i){
if(i==allNums.length){
var x = sum;
alert(0+"|"+selected2+"|"+cDist+","+x);
if(Math.abs(cDist)>Math.abs(x)){
cp();
cDist = x;
}
return sum;
}
if( i<allNums.length){
selected2[i]=true;
var dist1 = f(sum, allNums,i+1);
selected2[i] = false;
var dist2 = f(sum-allNums[i], allNums,i+1);
selThis = (Math.abs(dist1)>Math.abs(dist2));
if( selThis)
return dist2;
else
return dist1;
}
}
function absDis(n1,n2){
return Math.abs(n1-n2);
}
function cp( ){
selected.length=0;
for(var i=0;i<selected2.length;i++){
//selected.push(selected2[i]);
selected[i]=selected2[i];
}
}
</script>
</head>
<body>
<input id="numGroup1" type="text" size="20" value="1,2,3,4,5" />
<br>
<input id="numGroup2" type="text" size="20" value="9,-1,4,2" />
<br>
<input type="button" value="change" οnclick="change();" />
<br>
<input id="numGroup1_0" type="text" size="20" value="" />
<br>
<input id="numGroup2_0" type="text" size="20" value="" />
<br>
</body>
</html>
当然这里的实现使用的是简单遍历的方法,最坏情况下时间复杂度是2^n, 不过这只是第一版本,我会继续改进,也希望各位高手多多指点。
:-)