首页 新闻 会员 周边

算法题,求赐教!有点急

0
悬赏园豆:50 [待解决问题]

问题:
有若干个箱子,假设每个箱子的最大承重为 MaxW 。有一批物品,它们的重量分别为w1、w2...Wn,假设每个物品的重量都不超过箱子承重。
写个算法,用最少的箱子装完所有物品,并列出每个箱子装载的物品重量?

举个例子:
int[] Wn={8,5,19,5,5,11,5,4,2,17}
int MaxW=20

最少箱子数应该是4个,每个箱子装的物品的重量分别是 {11,5,4} {8,5,5,2} {19} {17}

 

PS:能用代码大佬可以直接上代码,能讲思路的就直接讲思路

DevenLiu的主页 DevenLiu | 初学一级 | 园豆:25
提问于:2018-07-08 22:53
< >
分享
所有回答(7)
0

这貌似就是贪心。

Bluto | 园豆:317 (菜鸟二级) | 2018-07-09 08:35

昨晚睡觉前,突然灵感来了,用了一个循环和回溯搞定了,但不知道是不是最合理的解决方案

支持(0) 反对(0) DevenLiu | 园豆:25 (初学一级) | 2018-07-09 10:05
0

首先至少5个,你少一个5的物品

思路:

1.数组排序

2.增序或逆序遍历数组,在数组中找跟(MaxW-win[i])最相近的

3.直到数组遍历完成

小光 | 园豆:1766 (小虾三级) | 2018-07-09 10:27

首先非常感谢朋友给解题思路,此法最先就已尝试,可能是能力有限,没能实现,不过现在已经用另一种方法实现了,再次感谢

支持(0) 反对(0) DevenLiu | 园豆:25 (初学一级) | 2018-07-09 10:30
0

如果只有一个箱子,应该是背包问题(动态规划),现在有多个箱子,那就再加上贪心。

Uteki | 园豆:573 (小虾三级) | 2018-07-09 13:56
0

MaxW

for Wi in Wn

{

//箱子装一件

if Wi==MaxW 则 Wi 装箱子

}

 

for Wi,Wj in Wn

{

//箱子装两件

if Wi+Wj ==MaxW 则 Wi、Wj 装箱子

}

 

//箱子装n件

。。。

 

直到任意的 n 件都大于 MaxW结束(在实现时可以人为设定下,比如一个箱子最多装4件,就是4次for)

---------------------------------------------------------------------------

MaxW=MaxW-1;

再重复分割线上面的;

---------------------------------------------------------------------------

 

理论上这个出来的是最优解,但复杂度模型有问题。

我在这方面经验不多,想到的方法比较笨。

放逐人 | 园豆:694 (小虾三级) | 2018-07-09 16:40
0

先给数组排序,从小到大~,然后 开始从前往后加和,加到第n个若大于maxw 就给箱子计数加1~然后 再从第n个数开始加和。。后面的以此类推

队长给我球。 | 园豆:324 (菜鸟二级) | 2018-07-09 17:44
0

代码:

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

拿着菜刀 | 园豆:236 (菜鸟二级) | 2018-07-12 09:36

虽然过去这么久了,没想到还有人回帖,很感谢哈,不过这个这位朋友的算法不正确

支持(0) 反对(0) DevenLiu | 园豆:25 (初学一级) | 2018-08-24 09:30
0

思路是这样的,要想箱子最少,那么装箱的重量最好等于20,次之则逼近20.

用20与这个10个数做差int[] Wn={8,5,19,5,5,11,5,4,2,17}
int MaxW=20

那么差值集合是int [] Wn1={12,15,1,15,15,9,15,16,18,3}

最理想的最小值为P=(8+5+19+5+5+11+5+4+2+17)/20=81/20大于4

最理想的最大值为Q=数组的长度=10,总重量为81吨,最重承重为20,起码要5个。

楼主的4个肯定是错的,最理想情况下也要5个,楼主答案里少了个5,数组是10个数好么?

所以可以确定范围是5到10个,如果是10箱,浪费的运量L=10*20-81=119,119/20<6

所以可以确定理论上的最小值为5,那么考虑实际上会有偏差,所以最小值要么是5要么是6

然后算法验证:

for(int i=0;i<wn.length;i=i+n){

  while(wn[i]+wn[i+1]+....wn[i+n])>20{

   print(wn[i],wn[i+1],wn[i+n-1])

}

}

{8,5}差集为{7}

{19}差集为{1}

{5,5}差集为{10}

{11,5,4}差集为{0}

{2,17}差集为{1}

差集和为19与20*5-81=19相验证且19<20可以确定是一组最优解理论上的最小值与实际符合。即为5.若将4改为3

则P=80.理论最小值为80/20=4.

但我们循环出来的结果为

{8,5}差集为{7}

{19}差集为{1}

{5,5}差集为{10}

{11,5,3}差集为{1}

{2,17}差集为{1}

这时实际值为5,理论值为4,怎么验证呢?差集中的最大值10与任一项的和相比。若差集10大,则为4,若差集10小则为5级理论值+1

good_idea | 园豆:74 (初学一级) | 2018-07-18 11:50
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册