c語言數據結構:01背包問題-------動態規划


兩天的時間都在學習動態規划:小作業(01背包問題:)

數據結構老師布置的這個小作業還真是讓人傷頭腦,自己實在想不出來了便去網上尋找講解,看到一篇不錯的文章:

http://www.cnblogs.com/sdjl/articles/1274312.html -------通過金礦模型介紹動態規划

但是----------------------------------------

兩天的時間才完成這個lab

總結:1.思維思路要清晰。2.題目信息要看清楚。3.改代碼過程中注意小變量的數值是否同步變化。

01背包問題思路(自頂向下):

背包承重為U。假設有十個物品,從左往右依次編號排列,可以采取如下步驟:

1.站在第10個物品處,一個物品只有選擇和未被選擇兩種情況,如果選擇了當前物品,那么選了它之后跟不選它所得到的價值誰大一點?其實我們采用遞歸兩種情況都會考慮的

i:當前物品重量大於U,那肯定就不能選擇這個物品,直接就考慮前9個物品的選擇情況了,此時去看第九個物品。

ii:當前物品重量小於U,可以選擇也可以不選擇,但是我們要看哪種情況更好,更優:選擇這個物品,假設前9個物品的選擇最優情況(此時背包容量會變小,因為選擇了第10個物品)我們已經得知了,此時可以得到在選擇第10個物品的情況下的價值,而如果不選擇這個物品,那么我們同樣假設前9個物品的最優選擇情況(此時背包容量還是U)已經得知了,那么我們從這選與不選的兩種情況中選擇最大的一種方案下就是原問題的最優解了。

iii:這是遞歸的過程,每個問題都需要有前面的最好的選擇方案才可以得出最優解,所以需要一個遞推邊界情況,當考慮第一個物品的時候,也就是考慮的物品中剩余的最后一個的時候,如果不選,因為前面已經沒有物品了,所以什么也放不進背包,得到的價值是0;如果選了,那就是當前物品的價值。

 

貼代碼:

#include<stdio.h>
#include<math.h>
#include<string.h>
int max_o,max_w;
#define max_o (3)
#define max_w (50)
int weight[max_o];   //用來存儲物品重量
int value[max_o];    //用來存儲物品價值
int pri[max_o];       //用來標記物品是否被選擇
int maxval[max_o]; //用來作備忘

void inia()
{
int j;
for(j=0;j<max_o;j++)
maxval[j]=0;
}

void inib()
{
int j;
for(j=0;j<max_o;j++)
{
pri[j]=0;
}
}

int max(int a,int b)
{
return a>b?a:b;
}
int getmax(int maxweight,int max_n) 
{
int maxret;

int o,k;

if(maxval[max_n]!=0) 

return maxval[max_n];

if(max_n==0)
{
if(weight[max_n]>maxweight)
maxret=0;
else {
maxret=value[max_n];
pri[max_n]=max_n;
}
}
else if(weight[max_n]<=maxweight) 
{ 
o=getmax(maxweight-weight[max_n],max_n-1)+value[max_n];
k=getmax(maxweight,max_n-1);
if(o>k)
pri[max_n]=max_n;
maxret=max(o,k);
}
else
{
maxret = getmax(maxweight,max_n-1);
}
maxval[max_n] = maxret;

return maxret;
}
void main()
{ int i;
inia();
inib();
for(i=0;i<max_o;i++)
{
scanf("%d%d",&weight[i],&value[i]);
}
printf("%d\n",getmax(max_w,max_o-1));
for(i=0;i<max_o;i++)
{
if(pri[i]!=0)
printf("第%d個物品被選擇\n",pri[i]+1);
}
}

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM