c語言01背包問題誰能簡單說下
c語言的窮舉法的背包問題
根據(jù)題目c1,c2是一組01組合的數(shù)組,也就是2個n位2進制數(shù)。
所以我的代碼邏輯就是,c1,c2初值分別是00000....以及111111....,之后循環(huán)執(zhí)行c1+1;c2-1(2進制加減運算),最大執(zhí)行次數(shù)2的n次方-1(n位2進制數(shù)最大數(shù))
代碼實現(xiàn)功能,窮舉所有可能方案,返回:第一個/最后一個找到的可行方案。
函數(shù)intqj(BAGc1,BAGc2,intn,int*bws,intflag);
當(dāng)flag=1返回第一個可行方案,flag=0查找所有方案并返回最后一個可行方案
我測試時,flag傳值0,需要自己改!!
由于迭代順序,同樣實驗數(shù)據(jù),返回的結(jié)構(gòu)和你案例結(jié)構(gòu)不一樣,我在下圖標(biāo)注了。
#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進制組合,返回最后一個可行方案(可能有多個方案)。
//參數(shù):c1背包1,c2背包2,n書本個數(shù),bws所有書本重量,標(biāo)識: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("請輸入書本的數(shù)量:\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);
//------------------------------打印結(jié)果-----------------------------
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位二進制數(shù),
{
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("-----------------窮舉結(jié)束------------------\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時,如果還有容量,那么返回的應(yīng)該是第一個物品的重量而不是0。你可以改變?nèi)萘緾或物品參數(shù)來檢驗算法的邏輯正確性。
關(guān)于輸出選擇的物品,我加了一個數(shù)組,用來標(biāo)記選擇的物品。因為做完所有遞歸后只有最外層的標(biāo)記是有效的,所以最后用了一個for循環(huán)來完成各層的標(biāo)記。下面是改動后的程序:
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語言)
本文發(fā)布于:2023-02-28 18:53:00,感謝您對本站的認可!
本文鏈接:http://m.newhan.cn/zhishi/a/167758772546335.html
版權(quán)聲明:本站內(nèi)容均來自互聯(lián)網(wǎng),僅供演示用,請勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請與我們聯(lián)系,我們將在24小時內(nèi)刪除。
本文word下載地址:c語言背包問題(C語言背包問題).doc
本文 PDF 下載地址:c語言背包問題(C語言背包問題).pdf
| 留言與評論(共有 0 條評論) |