问题描述:给定一艘容量为C的船,给定一批货物,货物i的重量是wi,要求在船不超重的前提下,将尽可能多的货物装上船。
此题的解法较多,可以采取暴力搜索,也可以采取回溯法。从本质上讲,二者的基本思路是一样的,只不过对于问题的表现形式不同。
1、采用回溯法
#include <stdio.h>
int n, c,cw, bestw;
int *w;
void backtrack(int i)
{
if (i>n)
{
if(bestw<cw)
bestw=cw;
return;
}
if(cw+w[i-1]<=c)
{
cw+=w[i-1];
backtrack(i+1);
cw=cw-w[i-1];
}
backtrack(i+1);
}
int main()
{
int i;
printf("input the number of boxes and the volume of the ship:");
scanf("%d%d",&n,&c);
w=new int [n];
printf("input the weights of each box:");
for(i=0;i<n;i++)
scanf("%d",w+i);
backtrack(1);
printf("the result is %d.\n",bestw);
return 0;
}
2、加上限制,并输出最优解。限制的条件是如果可能取得最优解,进入右子树,否则不进入
#include <stdio.h>
int n, c,cw, bestw, rest;
int *w,*x;
void backtrack(int i)
{
int j;
if (i>n)
{
if(bestw<cw){
bestw=cw;
for(j=0;j<n;j++)
printf("%d ",x[j]);
printf("\n");
}
return;
}
rest=rest-w[i-1];
if(cw+w[i-1]<=c)
{
x[i-1]=1;
cw+=w[i-1];
backtrack(i+1);
cw=cw-w[i-1];
}
if(cw+rest>bestw){ //利用当前的剪枝策略进行处理,如果加上所有剩余的有可能超过当前的最优,搜索右子树
x[i-1]=0;
backtrack(i+1);
}
rest=rest+w[i-1];
}
int main()
{
int i;
printf("input the number of boxes and the volume of the ship:");
scanf("%d%d",&n,&c);
rest=0;
w=new int [n];
x=new int [n];
printf("input the weights of each box:");
for(i=0;i<n;i++){
x[i]=0;
scanf("%d",w+i);
rest=rest+*(w+i);
}
backtrack(1);
printf("the result is %d.\n",bestw);
return 0;
}
3、非递归迭代回溯
//非递归迭代回溯
#include <stdio.h>
int main()
{
int i,j,k;
int n, c,cw=0, bestw=0, rest=0;
int *w,*x,*bestx;
printf("input the number of boxes and the volume of the ship:");
scanf("%d%d",&n,&c);
w=new int [n];
x=new int [n];
bestx=new int [n];
printf("input the weights of each box:");
for(i=0;i<n;i++){
x[i]=0;
scanf("%d",w+i);
rest=rest+*(w+i);
}
i=1;
while(true){
while(i<=n && cw+w[i-1]<=c){
rest=rest-w[i-1];
cw=cw+w[i-1];
x[i-1]=1;
i++;
}
if(i>n)
{
for(j=0;j<n;j++)
bestx[j]=x[j];
bestw=cw;
}
else{
rest=rest-w[i-1];
x[i-1]=0;
i++;
}
while(cw+rest<=bestw){
i--;
while(i>0 && !x[i-1]){
rest=rest+w[i-1];
i--;
}
if(i==0){
printf("the best result is %d\n",bestw);
for(j=0;j<n;j++)
printf("%d ",bestx[j]);
putchar('\n');
break;
}
x[i-1]=0;
cw=cw-w[i-1];
i++;
}
}
return 0;
}
4、暴力搜索
#include <stdio.h>
#include <math.h>
int main()
{
int i,j,num;
int max,temp;
int *w;
int n,c;
printf("input the number of boxes and the volume of the ship:");
scanf("%d%d",&n,&c);
w=new int [n];
printf("input the weights of each box:");
for(i=0;i<n;i++)
scanf("%d",w+i);
max=0;
for(num=0;num<pow(2,n);num++)
{
temp=0; j=num;
for(i=0;i<n;i++)
{
if(j%2)
temp=temp+w[i];
j=j/2;
}
if(temp>max && temp<=c)
max=temp;
}
printf("the result is %d.\n",max);
return 0;
}