回溯-装载问题

装载问题

时限: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
 
输出样例
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();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/zw159357/article/details/79694253