兩天的時間都在學習動態規劃:小做業(01揹包問題:)html
數據結構老師佈置的這個小做業還真是讓人傷頭腦,本身實在想不出來了便去網上尋找講解,看到一篇不錯的文章:數據結構
http://www.cnblogs.com/sdjl/articles/1274312.html -------經過金礦模型介紹動態規劃post
可是----------------------------------------學習
兩天的時間才完成這個laburl
總結:1.思惟思路要清晰。2.題目信息要看清楚。3.改代碼過程當中注意小變量的數值是否同步變化。htm
01揹包問題思路(自頂向下):blog
揹包承重爲U。假設有十個物品,從左往右依次編號排列,能夠採起以下步驟:遞歸
1.站在第10個物品處,一個物品只有選擇和未被選擇兩種狀況,若是選擇了當前物品,那麼選了它以後跟不選它所獲得的價值誰大一點?其實咱們採用遞歸兩種狀況都會考慮的get
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); } }