動態規劃(1)0 1揹包同型別習題

2021-07-30 12:14:46 字數 2328 閱讀 4761

先看0-1揹包問題,揹包可承受重量為w,有n個物品,它們的價值和重量分別為vi , costi (i=1~n),問揹包最大可以裝多少價值的物品。

我們定義乙個函式f(w,i),表示可承受重量為w的揹包,對於1~i號物品選擇若干個裝入揹包的最大價值。

那麼對於物品i可放或者不可放,因此有

選擇不放入i號物品有f( w,i ) = f( w, i-1 ) 

選擇放入i號物品時f(w,i) = f( w-costi , i-1 )+ vi

當然選擇放入i號物品的前提條件是i號物品可以放入,即costi<=w

綜上有

並且,,有f(0,i)=0(i>=0), f(w,0)=0(w>=0)

在使用迴圈畫**的時候需要注意:

欲求f(w,i)得知道f(w,i-1), f(w-costi,i-1),我們將f(w,i)看成二維陣列中第w行,第i列,那麼即是要先計算w行,i列的上方和左上側元素

為了求出揹包有最大價值時放入的物品,我們從上面的分析知道當f(w,i)=f(w-costi,i-1)+vi時,第i個物品在揹包內,因此從**末位向上搜尋即可

所有**如下:

#include #include using namespace std;

struct _goods ;

void knapsack(int w, int n, struct _goods goods[ ] )

int weight = w ;

for( int i=n; i>=1; --i )

if (dp[weight][i] == goods[i].value + dp[weight - goods[i].cost][i-1])

cout << endl ;

}int main( )

knapsack(w, n, goods) ;

return 0;

}

下面再看另一題

對於n個不重複的數,我們要從中選出若干個數使他們的和恰好為m,求有多少中選法。

和0-1揹包相同,都是選擇或者不選擇,寫出遞推表示式即可

對於資料datas[1~n],和m,我們定義f(i,m)表示從datas[1~i]中選擇若干個數和為m的方法數。

因此有如果不選擇第i個數有 f( i,m ) = f( i-1,m )

如果第i個數小於等於m,我們選擇第i個數有f( i,m )= f( i-1, m-datas[ i ] )

因此當datas[ i ] <=m 有 f( i , m ) = f(i-1,m)+ f( i-1, m-datas[ i ] )

當datas[ i ] > m 有 f( i,m ) = f( i-1 , m )

對於f(i,m),我們根據以上分析知隻需要求出 f(i,m) 的上方及左上方的元素就可以求出f(i,m)

因此我們初始化f(1,x)( x<=m )即可,f(1,datas[1])=1,其餘為0,

m-datas[ i ]有可能為0,當m=0的時候定義f(i,0)=1。也可以將datas[i]<=m分為小於和等於兩種情況討論

**如下:

#include using namespace std ;

int n,m;//資料個數,需合成數

int _datas[11];

void thesolution( )

for (int i = 2; i <= n; ++i)

for (int j = 1; j <= m; ++j)

if (_datas[i] < j)

dp[i][j] = dp[i - 1][j - _datas[i]] + dp[i - 1][j];//包含與不包含

else if (_datas[i] == j) //datas中無重複數字

dp[i][j] = 1 + dp[i - 1][j];//包含與不包含

else

dp[i][j] = dp[i - 1][ j ] ;

cout << dp[n][m] << endl;

}int main( )

對於輸出所有和為m的集合,我本想著先從f(n,m)到f(1,m)分別向上回溯**,後來想這樣好像不行

如果你知道怎麼做請告訴我!!

另乙個問題,如果給你n個數,取出若干個數求乘積恰好是m要你求出組合數目,以上討論應該知道了吧。注意餘數要為0

0-1揹包參考教材《演算法設計與分析基礎》(anany levitin著,第三版)

動態規劃(1) 01揹包問題

題目 現有n個物品,重量依次為w i 使用int weight表示 價值依次為 v i 使用 int values表示 現有乙個可裝重量為17的包 使用bag表示 求使揹包物品價值最大化的最優解,示例 全排列問題 深度搜尋字典序 author swing public class main 物品的價...

動態規劃 揹包

揹包經典問題 揹包問題01 乙個揹包容積為t 0 t 2000 現在有n 0 如下 includeusing namespace std int s 1005 bool f 3000 int main 揹包問題02 若每種物品有無限多個。從這n種物品中選取若干個裝入揹包內,使揹包所剩的空間最小。請求...

揹包(動態規劃)

一 01揹包問題 特點 每件物品僅有一件,可以選擇放與不放 有件物品和乙個容量為 的揹包。第 件物品的費用是 價值是 求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。用子問題定義狀態 f i v max f i 1 v f i 1 v c i w i 注意有意義當且僅當存...