装船问题

内容:

给定n个集装箱要装上一艘载重量为c的轮船,其中集装箱i的重量为wi。集装箱装载问题要求确定在不超过轮船载重量的前提下,将尽可能多的集装箱装上轮船(贪心算法中的装载问题讨论的是装载件数;本题讨论的是最大装载重量。)
由于集装箱问题是从n个集装箱里选择一部分集装箱,假设解向量为X(x1, x2, …, xn),其中xi∈{0, 1}, xi =1表示集装箱i装上轮船, xi =0表示集装箱i不装上轮船。

分析:

每组测试数据:第1行有2个整数c和n。C是轮船的载重量(0<c<30000),n是集装箱的个数(n≤20)。第2行有n个整数w1, w2, …, wn,分别表示n个集装箱的重量。
对每个测试例,输出两行:第1行是装载到轮船的最大载重量,第2行是集装箱的编号。

代码:

//装船问题
#include
using namespace std;
class goods{
int weight;
public:
goods(int w=0):weight(w)
{}
int get_w(){
return weight;
}
void set(int w){
weight=w;
}

};

//goods *g,集装箱列表
//int *best,待求解的最优装载方案
//int t,子集树数的层号。根节点在第0层,叶节点在第n层
//int n,集装箱的总数
//int &cw, 当前的轮船的荷载
//int bestcw ,当前的最大荷载
//int *x,满足当前最大荷载的装载方案
//int r剩余的集装箱重量和
void load(goods *g, int *x, int t, int n,int cw, int &bestcw ,int *best,int r,int c){
if(t>n) { //已经遍历的到叶子结点,得到了一个解决方案
if(cw>bestcw) {
for(int i=0;i<n;i++)
best[i]=x[i];
bestcw=cw;
}
}
else{
r=r-g[t].get_w();//剩余未处理的物品的重量和,与是否选取当前物品无关
if(cw+g[t].get_w()<=c){ // 根据题意中的约束条件进行剪枝
x[t]=1;
cw=cw+g[t].get_w(); //当前装入的物品的重量和
load(g,x,t+1,n,cw,bestcw,best,r,c);
cw=cw-g[t].get_w(); //回溯的需要
}
if(cw+r>bestcw) { //限界规则
x[t]=0;
load(g,x,t+1,n,cw,bestcw,best,r,c);
}
r=r+g[t].get_w(); //回溯
}
}
int main(){
int n,c,bestcw=0;
int *x,*best, r=0;
cout<<“请输入物品的件数和轮船的装载重量:";
cin>>n>>c;
goods *g;
g=new goods[n];
x=new int [n];
best=new int[n];
cout<<“请输入每件物品的重量:”;
for(int i=0;i<n;i++) {
int w; cin>>w; g[i].set(w);r=r+w;
}
load(g,x,0,n,0,bestcw,best,r,c);
cout<<bestcw<<endl;
for(i=0;i<n;i++)
cout<<best[i]<<" ";
cout<<endl;
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值