揹包問題之0 1揹包 一

2021-06-06 17:55:29 字數 1318 閱讀 4662

nyoj題目289 蘋果

解題思路:若設f[i][j]表示前i(1<=i<=n)個物品選擇放入容量為j(0<=j<=n)的揹包中能達到的最大總價值,則n個物品放入容量為w的揹包中能達到的最大總價值f[n][w]即為所求。而每個物品只有放入和不放入揹包中兩種選擇(這也是稱之為0—1揹包的原因,每個物品只能放入0個或1個),當第i個物品不放入容量為j的揹包時,則容量為j的揹包能達到的最大價值與前i-1個物品選擇放入容量為j的揹包時揹包能達到的最大價值相等,即此時f[i][j]=f[i-1][j]。當第i個物品放入容量為j的揹包時,則容量為j的揹包能達到的最大價值等於前i-1個物品選擇放入容量為j-w[i]的揹包能達到的最大價值與w[i]之和,即f[i][j]=f[i-1][ j-w[i] ] + w[i]。

故:  if(j>=w[i])

else

源**如下:

#include #define maxn 1001

int f[maxn][maxn];

int main()

printf("%d\n",f[n][w]);

} return 0;

}

空間優化:滾動陣列

優化思路:因為求f[i][j]時只用到f[i-1][j]和f[i-1][ j-w[i] ],且j<=j&&j-w[i]<=j,故f[i-1][j] 用過之後將其值改變也不會影響結果,所以可以用f[i-1][j]來存放f[i][j]的值,但此時必須按j從大到小依次求f[i][j]的值並存入f[i-1][j]中,因為求f[i][j]時要用到f[i][ j-w[i] ]的值且j-w[i] < j,故求f[i][j]前f[i-1][ j- w[i]]的值不能變。這樣就可以用f[j]來代替f[i][j],由於每加入乙個物品f[j]都要按j從大到小的順序求一次,故f[j]被稱為滾動陣列。

源**如下:

#include #include #define maxn 1001

int f[maxn];

int main()

,但是不要忘了只有當j>=w[i]才需要更改f[j]的值,即j原本下限為w[i];故j的下限downj=max  ,  w[j]  }。

源**如下:

#include #include #define maxn 1001

int w[maxn],v[maxn],f[maxn],sumi[maxn]; //sumi[i]用於儲存sum

int main()

for(i=1;i<=n;i++)

{ downj=(w-sumi[n]+sumi[i-1]);

if(downj=downj;j--)

if(f[j]

揹包問題之01揹包

01揹包就是說針對每一件物品,有選擇裝入或者放棄,是屬於動態規劃類的問題。現在假設我們有m件物品,各有價值,揹包承重為10,假設當前可用的承重量為v,當前在抉擇第m件物品是否放入,重量為w1,價值為v1,那麼,如果不放入,我們的價值應該保持不變,並與之前算出的最大價值相同,如果放入,放入後的價值就是...

揹包問題之0 1揹包

0 1揹包是最基本的揹包問題,其核心思路就在於每個物品的放與不放 每個物品最多只能放一次 題目有 n 個物品和乙個大小為 m 的揹包.給定陣列 a 表示每個物品的大小和陣列 v 表示每個物品的價值.問最多能裝入揹包的總價值是多大?樣例輸入 m 10,a 2,3,5,7 v 1,5,2,4 輸出 9 ...

揹包問題之0 1揹包

揹包問題大部分是這樣的 有乙個容量為v的揹包和一些物品。這些物品有兩個屬性,體積 和價值 每種物品只有乙個。要求用這個揹包裝下價值盡可能多的物品,求其最大價值。因為在最優解中,每個物品都有兩種可能的情況,即在揹包中存在 或者不存在 揹包中有0個或者1個該物品 因而被稱為0 1揹包問題。採藥 辰辰是個...