装载问题
时限:1000ms 内存限制:10000K 总时限:3000ms
描述
有两艘船,载重量分别是c1、 c2,n个集装箱,重量是wi (i=1…n),且所有集装箱的总重量不超过c1+c2。确定是否有可能将所有集装箱全部装入两艘船。
输入
多个测例,每个测例的输入占两行。第一行一次是c1、c2和n(n<=10);第二行n个整数表示wi (i=1…n)。n等于0标志输入结束。
输出
对于每个测例在单独的一行内输出Yes或No。
输入样例
7 8 2
8 7
7 9 2
8 8
0 0 0
8 7
7 9 2
8 8
0 0 0
输出样例
Yes
No
分析:对于给定能够装载指定重量的两条船,只要第一条船尽可能装满,然后用总重量减去其第一条船装载的数量,如果第二条船能够装下剩下的集装箱,即能够得到解,否则就不能得到解。
import java.util.*;
public class 装载问题 {
static int c1,c2,n; //c1,c2两个船分别装的重量,n集装箱数量
static int cw,bestw,r; //cw当前c1的装载量,bestw当前c1的最优装载量,r剩余的集装箱重量
static int[] wi=new int[100]; //每个集装箱装载的重量
public static void backstack(int k) {
if(k>n) {
//如果此时装载的重量大于最优解的重量
if(cw>bestw)
bestw=cw;
return;
}
r-=wi[k]; //首先将第一个集装箱拿出
if(cw+wi[k]<=c1) { //如果c1能够装下,改变当前c1的装载量
cw+=wi[k];
//递归寻找最优解
backstack(k+1);
cw-=wi[k];
}
//如果当前c1装载的重量加上集装箱剩余重量大于最优解,继续递归使寻找最优解直到递归到最后
if(cw+r>bestw)
backstack(k+1);
//如果本次没有找解,回溯
r+=wi[k];
}
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
c1=in.nextInt();
c2=in.nextInt();
n=in.nextInt();
while(c1!=0&&c2!=0&&n!=0) {
cw=0;
bestw=0;
r=0;
for(int i=1;i<=n;i++){
wi[i]=in.nextInt();
r+=wi[i];
}
backstack(1);
if(r-bestw<=c2)
System.out.println("Yes");
else
System.out.println("No");
c1=in.nextInt();
c2=in.nextInt();
n=in.nextInt();
}
}
}