package desk;
/**
* 一张桌子有n个不等长的桌腿,当最常桌腿大于所有桌腿数一半的时候,桌子可以平衡
* 每锯掉一条腿需要wi的代价,请用最小代价使桌子保持平衡
* @author Administrator
*
*/
public class Desk {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int n=6;
//长度数组
int[] l = {2,2,1,1,3,3};
//权重数组
int[] w = {4,3,5,5,2,1};
//锯掉标记数组,0为保留,1为锯掉
int[] b = {0,0,0,0,0,0};
desk(l, w, b, l.length-1, curW);
//desk1(l, w, b, 0, curW);
System.out.println(minW);
//System.out.println(isBlance(l, b));
}
//最小代价,初始化为所有代价和,此处省略
static int minW = 100;
//当前代价
static int curW = 0;
/**
* 从后往前递归,分两种情况,桌腿锯掉或是保留
* @param l 长度
* @param w 重量
* @param b 是否锯腿
* @param k 第k条腿
*/
public static void desk(int [] l, int [] w, int []b, int k, int curW) {
int temp[] = new int[b.length];
System.arraycopy(b, 0, temp, 0, b.length);
//特别注意这个判断和下一个判断之间的顺序
if(isBlance(l, temp)){//检测桌子是否平衡
for(int i=0; i<l.length; i++){
System.out.print(temp[i]);
}
System.out.println();
if(minW>curW){//平衡,考虑其代价
minW = curW;
}
}
if(k<0)
return;
//不锯第k条
desk(l, w, temp, k-1,curW);
//锯掉第k条
temp[k]=1;
desk(l, w, temp, k-1 ,curW+w[k]);
}
/**
* 从前往后递归,分两种情况,桌腿锯掉或是保留
* @param l 长度
* @param w 重量
* @param b 是否锯腿
* @param k 第k条腿
*/
public static void desk1(int [] l, int [] w, int []b, int k, int curW) {
int temp[] = new int[b.length];
System.arraycopy(b, 0, temp, 0, b.length);
//特别注意这个判断和下一个判断之间的顺序
if(isBlance(l, temp)){//检测桌子是否平衡
for(int i=0; i<l.length; i++){
System.out.print(temp[i]);
}
System.out.println();
if(minW>curW){//平衡,考虑其代价
minW = curW;
}
}
if(k>=l.length)
return;
//不锯第k条
desk1(l, w, temp, k+1,curW);
//锯掉第k条
temp[k]=1;
desk1(l, w, temp, k+1 ,curW+w[k]);
}
/**
* 使用动态规划求解
*/
/**
* @param l 桌腿长度数组
* @param b 是否锯掉数组,1锯掉
* @return 是否平衡
*/
public static boolean isBlance(int [] l, int []b) {
int max = 0;
int len = 0;
//找到数组中最大值max
for(int i=0; i<l.length; i++){
if(l[i]>max)
max = l[i];
if(b[i]==0)
++len;
}
//将没锯的桌子以长度为key统计出现次数
int count[] = new int[max+1];
for(int i=0; i<l.length; i++){
if(b[i]==0){
count[l[i]]++;
}
}
//找到长度最大桌腿,判断其次数是否大于一半
for(int i=max; i>=0; i--){
if(count[i]>0){
if(count[i]>(len/2))
return true;
else
break;
}
}
return false;
}
}