c语言01背包问题谁能简单说下
c语言的穷举法的背包问题
根据题目c1,c2是一组01组合的数组,也就是2个n位2进制数。
所以我的代码逻辑就是,c1,c2初值分别是00000....以及111111....,之后循环执行c1+1;c2-1(2进制加减运算),最大执行次数2的n次方-1(n位2进制数最大数)
代码实现功能,穷举所有可能方案,返回:第一个/最后一个找到的可行方案。
函数intqj(BAGc1,BAGc2,intn,int*bws,intflag);
当flag=1返回第一个可行方案,flag=0查找所有方案并返回最后一个可行方案
我测试时,flag传值0,需要自己改!!
由于迭代顺序,同样实验数据,返回的结构和你案例结构不一样,我在下图标注了。
#include<stdio.h>
#include<math.h>
#include<malloc.h>
#include<string.h>
typedefstructbag
{
intbweight;
char*books;
}BAG;
intqj(BAGc1,BAGc2,intn,int*bws,intflag);//穷举所有n位2进制组合,返回最后一个可行方案(可能有多个方案)。
//参数:c1背包1,c2背包2,n书本个数,bws所有书本重量,标识:flag=1找到第一个可行方案截止,flag=0查找所有方案
intcheckOverLoad(BAGc1,BAGc2,int*bws,intn);
voidadd2(char*nums);//2进制字符串+1运算
voidsub2(char*nums);//2进制字符串-1运算
intmain()
{
BAGc1,c2;
inti,n,*bws,sum=0;
printf("请输入两个背包的最大载重:\n");
scanf("%d%d",&c1.bweight,&c2.bweight);
printf("请输入书本的数量:\n");
scanf("%d",&n);
c1.books=(char*)malloc(sizeof(char)*(n+1));
c2.books=(char*)malloc(sizeof(char)*(n+1));
c1.books[0]=0;
c2.books[0]=0;
bws=(int*)malloc(sizeof(int)*n);
while(1)
{
sum=0;
printf("请输入每本书的重量:\n");
for(i=0;i<n;i++)
{
scanf("%d",&bws[i]);
sum+=bws[i];
}
if(sum<=c1.bweight+c2.bweight)
break;
el
printf("书本重量和超过背包负重和!请重新输入\n\n");
}
qj(c1,c2,4,bws,0);
//------------------------------打印结果-----------------------------
printf("\n输出:\n");
printf("book");
for(i=0;i<n;i++)
printf("%d",bws[i]);
printf("\n");
printf("c1%s\n",c1.books);
printf("c2%s\n",c2.books);
}
intqj(BAGc1,BAGc2,intn,int*bws,intflag)//穷举所有n位二进制数,
{
inti,max=(int)pow(2,n)-1;
char*nums1,*nums2;
nums1=(char*)malloc(sizeof(char)*(n+1));
nums2=(char*)malloc(sizeof(char)*(n+1));
printf("---------开始穷举所有可能的组合----------\n");
memt(c1.books,'0',n);
memt(c2.books,'1',n);
c1.books[n]=c2.books[n]=0;
printf("%s\n",c1.books);
printf("%s\n",c2.books);
if(checkOverLoad(c1,c2,bws,n)==0)
{
memt(nums1,0,n+1);
memt(nums2,0,n+1);
strcpy(nums1,c1.books);
strcpy(nums2,c2.books);
if(flag==1)
return0;
}
printf("\n");
for(i=0;i<max;i++)
{
add2(c1.books);
sub2(c2.books);
printf("%s\n",c1.books);
printf("%s\n",c2.books);
if(checkOverLoad(c1,c2,bws,n)==0)
{
memt(nums1,0,n+1);
memt(nums2,0,n+1);
strcpy(nums1,c1.books);
strcpy(nums2,c2.books);
if(flag==1)
return0;
}
printf("\n");
}
printf("-----------------穷举结束------------------\n");
memt(c1.books,0,n+1);
memt(c2.books,0,n+1);
strcpy(c1.books,nums1);
strcpy(c2.books,nums2);
free(nums1);
free(nums2);
return0;
}
voidadd2(char*nums)//2进制字符串加1
{
inti,n=strlen(nums),jin=0;
for(i=n-1;i>=0;i--)
{
if(nums[i]=='0'&&i==n-1)
{
nums[i]='1';
break;
}
elif(nums[i]-'0'+jin==1&&i<n-1)
{
nums[i]='1';
break;
}
el
{
jin=1;
nums[i]='0';
}
}
}
voidsub2(char*nums)//2进制字符串减1
{
inti,n=strlen(nums),j=0;
for(i=n-1;i>=0;i--)
{
if(nums[i]=='1'&&i==n-1)
{
nums[i]='0';
break;
}
elif(nums[i]-'0'-j==0&&i!=n-1)
{
nums[i]='0';
break;
}
el
{
nums[i]='1';
j=1;
}
}
}
intcheckOverLoad(BAGc1,BAGc2,int*bws,intn)//检查是否超载。超载返回1,否返回0
{
inti,sum1=0,sum2=0;
for(i=0;i<n;i++)
if(c1.books[i]=='1')
sum1=sum1+bws[i];
el
sum2=sum2+bws[i];
if(sum1>c1.bweight)
{
printf("背包1超载!\n");
return1;
}
if(sum2>c2.bweight)
{
printf("背包2超载!\n");
return1;
}
printf("方案可行!\n");
return0;
}
C语言 背包问题 递归算法
提问者的这程序中用了递归算法,不过逻辑上有个小bug,就是在判断到n==0时,如果还有容量,那么返回的应该是第一个物品的重量而不是0。你可以改变容量C或物品参数来检验算法的逻辑正确性。
关于输出选择的物品,我加了一个数组,用来标记选择的物品。因为做完所有递归后只有最外层的标记是有效的,所以最后用了一个for循环来完成各层的标记。下面是改动后的程序:
inta[5]={0};
intMaxW(intn,intC,int*Volunme,int*Weight)
{
intW=0,W1=0,W2=0;
if(n==0)
{
if(C>=Volunme[0])
{
a[0]=1;
returnW=1;
}
el
return0;
}
elif(C>=Volunme[n])//背包剩余空间可以放下物品n
{
W1=MaxW(n-1,C-Volunme[n],Volunme,Weight)+Weight[n];//放入n所能得到的重量
W2=MaxW(n-1,C,Volunme,Weight);//不放n所能得到的重量
W=(W1>W2?W1:W2);
a[n]=(W1>W2?1:0);
}
el//背包空间放不下n,返回判断放n-1的情况
{
returnMaxW(n-1,C,Volunme,Weight);
}
returnW;
}
intmain(void)
{
intn=5;intC=7;
intVolunme[]={1,2,3,4,5};
intWeight[]={1,2,5,7,8};
printf("最大重量为%d\n",MaxW(n-1,C,Volunme,Weight));
for(inti=n-2;i>=0;i--)
{
a[i]=0;
if(a[i+1]==1)
{
C-=Volunme[i+1];
Weight[i+1]=0;
}
MaxW(i,C,Volunme,Weight);
}
printf("选择的物品号是:");
for(inti=0;i<5;i++)
{
if(a[i]==1)
printf("#%d",i+1);
}
printf("\n");
return0;
}
C语言背包问题递归算法
c语言背包问题,求高手解答
背包问题(C语言)
本文发布于:2023-02-28 18:53:00,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/zhishi/a/167758772546335.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:c语言背包问题(C语言背包问题).doc
本文 PDF 下载地址:c语言背包问题(C语言背包问题).pdf
留言与评论(共有 0 条评论) |