轮船装载问题
问题描述:
有两艘船和需要装载的n吨货箱,第一个货箱最大的装载量为C1,第二艘的载重量为c2,n个货箱的重量分别是w1,w2,w3......wn,且w1+w2+w3+w4.....wn<=c1+c2,希望找出一种可以将全部的货都装走的方案,若有,找到该方法。
设计思想:
借用辅助队列,将问题抽象出来一棵子集数,每一个货箱都可以作为一层来处理,每层的开始都用-1来标识,先让-1入队,然后装入就往左分支出一种情况,不装入就往右分支出一种情况,将装入和不装入的结果先入队列保存,这样会有2的n次方种情况,通过判断是否装的下来对这些情况筛选,最终可以将一艘完美的装下。代码加注释
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
double MaxLoading(const vector<double> &w, const double c1)
{
double bestW = 0;
queue<double> qw;
int n = w.size();
//-1表示到达层的尾部
qw.push(-1);
//当前的重量
double ew = 0;
//第i箱货物
int i = 0;
while (!qw.empty())
{
//放第i箱货物
if (ew + w[i] <= c1)
{
qw.push(ew + w[i]);
if (ew + w[i] > bestW)
{
bestW = ew + w[i];
}
}
//不放第i箱货物
qw.push(ew);
ew = qw.front();
qw.pop();
//如果一层已经结束
if (-1 == ew)
{
//如果考虑完最后一箱货物
if (i == n - 1)
{
return bestW;
}
else
{
qw.push(-1);
}
//如果出队的是-1,则再出队一个元素
ew = qw.front();
qw.pop();
++i;
}
}
}
int main()
{
double c1, c2;
cout << "请输入c1,c2:";
cin >> c1 >> c2;
cout << "请输入n个货箱的重量:";
vector<double> w;
double tmp_w;
double total_w = 0;
while (cin >> tmp_w)
{
w.push_back(tmp_w);
total_w += tmp_w;
}
if (total_w <= c1 || total_w <= c2)
{
cout << "一艘船即可!" << endl;
exit(0);
}
if (total_w > c1 + c2)
{
cout << "无法装载!" << endl;
exit(0);
}
double Mc1 = MaxLoading(w, c1);
if (total_w - Mc1 <= c2)
{
cout << "可以装载!" << endl;
cout << "第一个船装" << Mc1 << '\t' << "第二个船装" << total_w - Mc1 << endl;
}
else
{
cout << "无法装载" << endl;
}
return 0;
}
//50 50
// 20 40 40
测试结果
注:
这里面用了一个头文件#include , 向量 vector 是一种对象实体, 能够容纳许多其他类型相同的元素, 因此又被称为容器。 与string相同, vector 同属于STL(Standard Template Library, 标准模板库)中的一种自定义的数据类型, 可以广义上认为是数组的增强版 vector 容器与数组相比其优点在于它能够根据需要随时自动调整自身的大小以便容下所要放入的元素。转自
原出处