先看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 注意有意義當且僅當存...