有一批共n个集装箱要装上两艘载重量分别为c1和c2的轮船,其中集装箱i的重量为wi,且w1+w2+…+wn≤c1+c2。 装载问题要求确定是否有一个合理的装载方案可将这些集装箱装上这两艘轮船。如果有,找出一种装载方案。
函数接口定义:
void dfs(int tw,int rw,int op[],int i);
bool solve();
其中tw
表示选择的集装箱重量和,rw
表示剩余集装箱的重量和,op
表示一个解,即一个选择方案,i
表示考虑的集装箱i
。
裁判测试程序样例:
#include <stdio.h>
#include <string.h>
#define MAXN 20 //最多集装箱个数
#include <iostream>
using namespace std;
//问题表示
int w[MAXN]={0}; //各集装箱重量,不用下标0的元素
int n;
int c1,c2;
int maxw=0; //存放第一艘轮船最优解的总重量
int x[MAXN]; //存放第一艘轮船最优解向量
void dispasolution(int n) //输出一个解
{
for (int j=1;j<=n;j++)
if (x[j]==1)
printf("%d ",j);
cout<<endl;
for (int j=1;j<=n;j++)
if (x[j]==0)
printf("%d ",j);
}
void dfs(int tw,int rw,int op[],int i);
bool solve();
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>w[i];
cin>>c1>>c2;
int op[MAXN]; //存放临时解
memset(op,0,sizeof(op));
int rw=0;
for (int i=1;i<=n;i++)
rw+=w[i];
dfs(0,rw,op,1); //求第一艘轮船的最优解
if (solve()) //输出结果
{
dispasolution(n);
}
else
printf("No solution");
return 0;
}
/* 请在这里填写答案 */
输入格式:
第一行输入集装箱个数n,第二行依次输入n个集装箱的重量wi,第三行输入两艘载重量c1和c2。
输出格式:
第一行输出第一艘选取的集装箱编号,第二行输出第二艘选取的集装箱编号。(编号按输入顺序从1开始)
若没有合理的装载方案,输出“No solution”。
输入样例1:
3
10 40 40
50 50
输出样例1:
1 2
3
解题方法:
由于集装箱放在第一或第二条船上。所以该问题可以采用二叉树的存储结构。以数组的形式将集装箱存储的位置结果保存(这里用op[i]为0或1来表示存储的第一或者第二条船)。
我们采用的算法是回溯法,先尽可能把集装箱装在第一条船上(等同于在二差树里面把op[i]==0),每次先判断当前的tw表示选择的集装箱重量和是不是大于第一个集装箱的容纳量。如果大于就把下一个集装箱放在第二个集装箱。然后通过不断递归可以达到深度扩展的功能。