今天在博客园中看到一个博问,就写了下实现代码。
问题:
有若干个箱子,假设每个箱子的最大承重为 MaxW 。有一批物品,它们的重量分别为w1、w2...Wn,假设每个物品的重量都不超过箱子承重。
写个算法,用最少的箱子装完所有物品,并列出每个箱子装载的物品重量?
代码:
public static void main(String[] args){ //初始化长度为50的数组 Integer[] ints=new Integer[20]; //使用随机数机制,随机获取小于20的50个整数,添加到数组 for(int i=0;i<ints.length;i++){ ints[i]=(int)(1+Math.random()*20); System.out.print(ints[i]+" "); } //使用选择排序将数据由大到小排序 int tmp; for(int i=0;i<ints.length;i++){ for (int j=0;j<ints.length;j++){ if(ints[i]>ints[j]){ tmp=ints[i]; ints[i]=ints[j]; ints[j]=tmp; } } } System.out.println(); //集合排序后,打印输出 for(int i=0;i<ints.length;i++){ System.out.print(ints[i]+" "); } System.out.println(); //实现随机组合装箱为20容积的箱子 //如何去获取装箱组合 int max=20;//初始化箱子的容积 int identSub=ints.length-1;//初始化由后到前取数组元素的下标 int element=0;//初始化获取的数组元素相加的和 int groupNum=0;//初始化组合的数量为0 //从前向后取集合中的每个数据 out:for(int i=0;i<ints.length;i++){ //每一次的第一层循环都将数组相加和设置为0 element=0; System.out.print("{"); element=ints[i]; System.out.print(ints[i]+" "); //从后向前取每个元素数据,但需要添加标识,记录下次取数的位置 for(;identSub>i;identSub--){ element+=ints[identSub]; //判断当前获取的前后值和是否大于了箱子的容积,如果大于跳出本次循环 if (element>max){ groupNum++; break; } System.out.print(ints[identSub]+" "); } //如果前后获取到同一个数据时,就跳出整个嵌套循环 if(identSub==i){ System.out.println("}"); groupNum++; break; } System.out.print("}"); System.out.println(); } System.out.println("需要使用"+max+"容积的箱子数为:"+groupNum); }
代码执行结果:
3 15 14 19 13 4 10 4 20 3 1 7 13 8 18 18 20 5 9 8
20 20 19 18 18 15 14 13 13 10 9 8 8 7 5 4 4 3 3 1
===组合装箱开始===
{20 }
{20 }
{19 1 }
{18 }
{18 }
{15 3 }
{14 3 }
{13 4 }
{13 4 }
{10 5 }
{9 7 }
{8 8 }
===组合装箱结束===
需要使用20容积的箱子数为:12