问题描述:有一批共n个集装箱要装上两艘载重量分别是c1和c2的轮船,其中,集装箱i的重量为wi,且wi求和结果小于c1+c2。要求确定是否有一个合理的装载方案可将这n个集装箱装上这两艘船。
解决的思路就是尽量将第一支船装满,再比较剩下的集装箱的重量如果比第二艘船的载重量大说明装不下,否则就装得下。
输入:
多个测例,每个测例的输入占两行。第一行一次是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
代码如下:
public class Main {
static int n;//集装箱数量
static int w[];//集装箱重量数组
static int c1;//第一艘轮船的载重量
static int c2;//第二艘轮船的载重量
static int cw;//当前载重量
static int bestw;//当前最优载重量
static int r=0;//剩余集装箱的总质量
static int []x;//当前解
static int []bestx;//当前最优解
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Vector<String>list=new Vector<String>();
c1=sc.nextInt();
c2=sc.nextInt();
n=sc.nextInt();
while(n!=0)
{
String str="";
w=new int[n+1];
x=new int[n+1];
bestx=new int[n+1];
for(int i=1;i<=n;i++)
{
w[i]=sc.nextInt();
r+=w[i];
}
backtrack(1);
r-=bestw;
if(r>c2)
{
list.add("No");
}
else
{
list.add("Yes");
}
bestw=0;
r=0;
c1=sc.nextInt();
c2=sc.nextInt();
n=sc.nextInt();
}
for(int i=0;i<list.size();i++)
System.out.println(list.get(i));
}
public static void backtrack(int i)
{//搜索第i层节点
if(i>n)
{//节点搜索完毕
if(cw>bestw)
{
for(int j=1;j<=n;j++)
bestx[j]=x[j];
bestw=cw;
}
return;
}
r-=w[i];
//搜索左子树
if(cw+w[i]<=c1)
{
x[i]=1;
cw+=w[i];
backtrack(i+1);
cw-=w[i];
}
if(cw+r>bestw)
{//进入右子树
x[i]=0;
backtrack(i+1);
}
r+=w[i];
}
}
这个问题中,当时我遇到的最大问题就是没有及时恢复现场,诸位一定要记住哦!!