**01揹包問題
動態規劃的基本思想:
動態規劃演算法可分解成從先到後的4個步驟:
1. 描述乙個最優解的結構,尋找子問題,對問題進行劃分。
2. 定義狀態。往往將和子問題相關的各個變數的一組取值定義為乙個狀態。某個狀態的值就是這個子問題的解(若有k個變數,一般用k維的陣列儲存各個狀態下的解,並可根 據這個陣列記錄列印求解過程。)。
3. 找出狀態轉移方程。一般是從乙個狀態到另乙個狀態時變數值改變。
4.以「自底向上」的方式計算最優解的值。
5. 從已計算的資訊中構建出最優解的路徑。(最優解是問題達到最優值的一組解)
其中步驟1~4是動態規劃求解問題的基礎,如果題目只要求最優解的值,則步驟5可以省略。
揹包問題
01揹包: 有n件物品和乙個重量為m的揹包。(每種物品均只有一件)第i件物品的重量是w[i],價值是p[i]。求解將哪些物品裝入揹包可使價值總和最大。
完全揹包: 有n種物品和乙個重量為m的揹包,每種物品都有無限件可用。第i種物品的重量是w[i],價值是p[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包重量,且價值總和最大。
多重揹包: 有n種物品和乙個重量為m的揹包。第i種物品最多有n[i]件可用,每件重量是w[i],價值是p[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包重量,且價值總和最大。
01揹包問題:
這是最基礎的揹包問題,特點是:每種物品僅有一件,可以選擇放或不放。
用子問題定義狀態:即c[i][v]表示前i件物品恰放入乙個重量為m的揹包可以獲得的最大價值。則其狀態轉移方程便是:
c[i][m]=max
這個方程非常重要,基本上所有跟揹包相關的問題的方程都是由它衍生出來的。所以有必要將它詳細解釋一下:「將前i件物品放入重量為m的揹包中」這個子問題,若只考慮第i件物品的策略(放或不放),那麼就可以轉化為乙個只牽扯前i-1件物品的問題。如果不放第i件物品,那麼問題就轉化為「前i-1件物品放入容量為v的揹包中」,價值為c[i-1][m];如果放第i件物品,那麼問題就轉化為「前i-1件物品放入剩下的重量為m-w[i]的揹包中」,此時能獲得的最大價值就是c[i-1][m-w[i]]再加上通過放入第i件物品獲得的價值p[i]。
**:
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7view code#define clr(a,b) memset(a,b,sizeof(a))
8#define inf 0x7f7f7f7f
9#define m 1050
10using
namespace
std;
11int v[200][200];//
前i個物品裝入容量為j的揹包中獲得的最大價值
12int max(int a,int
b)13
1819
int knapsack(int n,int w,int v,int x,int
c)20
40else
41 x[i]=0;42
}43 printf("
選中的物品是:\n");
44for(i=0; i)
45 printf("
%d "
,x[i]);
46 printf("\n"
);47
return v[n-1
][c];
4849}50
51int
main()
5275
/*76
1077578
3 4 5 3 2
793 2 6 4 3
80*/
01揹包演算法
核心 狀態轉換方程 01揹包問題 容量為10的揹包,有5種物品,每種物品只有乙個,其重量分別為5,4,3,2,1,其價值分別為1,2,3,4,5。設計演算法,實現揹包內物品價值最大。如下 輸出14 include include using namespace std int main int v ...
演算法 01揹包
揹包最大容量10,有以下5個商品及其價值,試求揹包所能容納的最大價值。序號1 2345 重量226 54價值6 3546 如下 include include define max v 100 using namespace std struct good 動態規劃求解 n 商品個數 m 揹包最大重...
演算法(揹包問題 01揹包問題)
01揹包問題 有 n 件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i 件物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品數量和揹包容積。接下來有 n 行,...