1002装载.docx
- 文档编号:4324003
- 上传时间:2022-11-29
- 格式:DOCX
- 页数:14
- 大小:16.93KB
1002装载.docx
《1002装载.docx》由会员分享,可在线阅读,更多相关《1002装载.docx(14页珍藏版)》请在冰豆网上搜索。
1002装载
[回溯]装载问题
TimeLimit:
1SecMemoryLimit:
128MB
Submissions:
13Solved:
6
[Submit][Status][Discuss]
Description
有两艘船,载重量分别是c1、c2,n个集装箱,重量是wi(i=1…n),且所有集装箱的总重量不超过c1+c2。
确定是否有可能将所有集装箱全部装入两艘船。
Input
多个测例,每个测例的输入占两行。
第一行一次是c1、c2和n(n<=10);第二行n个整数表示wi(i=1…n)。
n等于0标志输入结束。
Output
对于每个测例在单独的一行内输出Yes或No。
SampleInput
782
87
792
88
000
SampleOutput
Yes
No
HINT
#include"stdio.h"
#defineMAXARRAY10000
#definePUSH(A,B){sl[sp]}=A;sr[sp]=B;sp++}
#definePOP(A,B){sp--;A=sl[sp];b=sr[sp];}
voidquicksort(inta[],intl,intr)
{
staticintsl[MAXARRAY],sr[MAXARRAY],sp;
inti,j,p,t;
sp=0;
PUSH(l,r);
while(sp)
{
POP(l,r);
i=l;j=r;p=a[(i+j)/2];
while(i<=j)
{
while(a[i]
while(a[j]>p)j--;
if(i<=j)
{
t=a[i];a[i]=a[j];a[j]=t;
i++;j++;
}
}
if(l if(i } } voidmain() { inta[MAXARRAY]; inti; intn; scanf("%d",&n); for(i=0;i scanf("%d",&a[i]); quicksort(a,0,n-1); for(i=0;i printf("%d\n",a[i]); } 二、 #include usingnamespacestd; intbestw=0;//当前最多载重量 intcw=0;//当前载重量 intnum=3;//箱子数 intr=46;//剩余箱子重量 intbestx[3];//最重的情况下箱子的选择情况 voidload(int*w,intc,intn,int*x) { if(n>=num) { if(cw>bestw) { for(inti=0;i {bestx[i]=x[i]; bestw=cw; } } return; } r-=w[n];//************* if(cw+w[n]<=c) { cw+=w[n]; x[n]=1; load(w,c,n+1,x); cw=cw-w[n]; } if(cw+r>bestw)//************************* { x[n]=0; load(w,c,n+1,x); } r+=w[n];//********* } .回溯法——装箱问题算法2010-07-2811: 02: 46阅读26评论0字号: 大中小订阅. 问题描述: 有n个集装箱要装到俩艘船上,每艘船的容载量分别问c1,c2,第i个集装箱的重量为w[i],同时满足: w[1]+w[2]+...+w[n]<=c1+c2;求确定一个最佳的方案把这些集装箱装入这俩艘船上。 最佳方案的方法: 首先将第一艘船尽量装满,再把剩下的装在第二艘船上; 第一艘船尽量装满等价于从n个集装箱选取一个子集,使得该子集的总重量与第一艘船的重量c1最接近,这样就类似于0-1背包问题; 问题解空间: (x1,x2,x3...xn),其中每个xi为0表示不装在第一艘船上,为1表示在第一艘船上; 约束条件: 1.可行性约束条件: w1*x1+w2*x2+...wi*xi+...+wn*xn<=c1; 2.最优解约束条件: remain+cw>bestw(remain表示剩余集装箱重量;cw表示当前已装上的集装箱的重量;bestw表示以前确定的集装箱装入c1中的重量) 利用递归求解方法: #include #include usingnamespacestd; int*w;//存放每个集装箱的重量 intnumber;//集装箱的数目 intc;//第一艘船的承载量 intcw;//当前载重量; intremain;//剩余载重量; int*x;//存放搜索时每个集装箱是否选取; intbestw;//存放最优的放在第一艘船的重量; int*bestx;//存放最优的集装箱选取方案; voidbacktrace(intk) { if(k>number) { for(inti=1;i<=number;i++) { bestx[i]=x[i]; } bestw=cw; return; } else { remain-=w[k]; if(cw+w[k]<=c) { x[k]=1; cw+=w[k]; backtrace(k+1); cw-=w[k]; } if(remain+cw>bestw) { x[k]=0; backtrace(k+1); } remain+=w[k]; } } intbestSoution(int*w,intnumber,intc) { remain=0; for(inti=1;i<=number;i++) { remain+=w[i]; } bestw=0; backtrace (1); returnbestw; } intmain() { cout<<"请输入集装箱的数目: "; cin>>number; w=newint[number+1]; x=newint[number+1]; bestx=newint[number+1]; cout<<"请输入第一艘船的装载量: "; cin>>c; cout<<"请输入每个集装箱的重量: "; cout< for(inti=1;i<=number;i++) { cout< cin>>w[i]; } bestw=bestSoution(w,number,c); for(i=1;i<=number;i++) { cout< } cout< cout< } 另一种描述方法: #include #include usingnamespacestd; int*bestx;//存放最优解的0,1; int*x;//每次存放集装箱是否选取的,0: 未选取;1: 选取; int*w;//每个集装箱的重量; intnumber;//集装箱的数量 intbestw;//最优解的集装箱放入第一艘船的总重量; intc;//第一艘船能容纳的重量; boollegal(int*x,intk,intbestw) { intcw=0;//当前集装箱的总重量; intremain=0;//当前剩余的集装箱的数量; for(inti=1;i<=number;i++) remain+=w[i]; for(i=1;i<=k;i++) { cw+=(x[i]*w[i]); remain-=w[i]; } if(cw>c) { returnfalse; } if(remain+cw<=bestw) { returnfalse; } returntrue; } voidBacktrace(intk) { if(k>number) { bestw=0; for(inti=1;i<=number;i++) { bestx[i]=x[i]; bestw+=(x[i]*w[i]); } } else { for(inti=1;i>=0;i--) { x[k]=i; if(legal(x,k,bestw)) { Backtrace(k+1); } } } } intmain() { inti=0; cout<<"请输入集装箱的数目: "; cin>>number; cout< w=(int*)malloc(sizeof(int)*(number+1)); cout<<"请输入第一艘船能容纳的重量: "; cin>>c; cout< cout<<"请输入每个集装箱的重量: "< for(i=1;i<=number;i++) { cout< cin>>w[i]; cout< } x=newint[number+1]; bestx=newint[number+1]; bestw=0; Backtrace (1); cout< for(i=1;i<=number;i++) { cout< } cout< cout< return0; } 利用非递归的求解方法: #include #include usingnamespacestd; int*bestx;//存放最优解的0,1; int*w;//每个集装箱的重量; intnumber;//集装箱的数量 intbestw;//最优解的集装箱放入第一艘船的总重量; intc;//第一艘船能容纳的重量; boolIsLood(intn,int*x) { intcw=0;//存放现在的重量; intremain=0; for(inti=1;i<=number;i++) { remain+=w[i]; } for(i=1;i<=n;i++) { cw+=x[i]*w[i]; remain-=w[i]; } if(cw>c) returnfalse; if(cw+remain<=bestw) returnfalse; returntrue; } intMaxLoading() { int*x;//每次存放集装箱是否选取的,0: 未选取;1: 选取; x=newint[number+1]; bestw=0; inti=1; x[1]=-1; while(i>0) { x[i]+=1; while(x[i]<=1&&(! IsLood(i,x))) { x[i]++; } if(x[i]<=1) { if(i==number) { bestw=0; for(intk=1;k<=number;k++) { bestw+=x[k]*w[k]; bestx[k]=x[k]; } } else { i++; x[i]=-1; } } else { i--; } } returnbestw; } intmain() { inti=0; cout<<"请输入集装箱的数目: "; cin>>number; cout< w=newint[number+1]; cout<<"请输入第一艘船能容纳的重量: "; cin>>c; cout< cout<<"请输入每个集装箱的重量: "< for(i=1;i<=number;i++) { cout< cin>>w[i]; cout< } bestx=newint[number+1]; bestw=0; bestw=MaxLoading(); cout< for(i=1;i<=number;i++) { cout< } cout< cout< return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 1002 装载