http://www.hawstein.com/posts/dp-knapsack.htmlhtml
http://www.cnblogs.com/wwwjieo0/archive/2013/04/01/2991238.html算法
http://blog.csdn.net/mu399/article/details/7722810數組
n顆寶石,體積v[i] 價值w[i] ,揹包體積Cpost
/**0-1 knapsack d(i, j)表示前i個物品裝到剩餘容量爲j的揹包中的最大重量**/ #include<cstdio> using namespace std; #define MAXN 1000 #define MAXC 100000 int V[MAXN], W[MAXN],x[MAXN]; int d[MAXN][MAXC]; int main(){ freopen("data.in", "r", stdin);///重定向輸入流 freopen("data.out", "w", stdout);///重定向輸出流 int n, C; while(scanf("%d %d", &n, &C) != EOF){ for(int i=0; i<n; ++i) scanf("%d %d", &V[i], &W[i]); for(int i=0; i<=n; ++i){ for(int j=0; j<=C; ++j){ d[i][j] = i==0 ? 0 : d[i-1][j]; if(i>0 && j>=V[i-1]) d[i][j] =max(d[i-1][j],d[i-1][j-V[i-1]]+W[i-1]); } } printf("%d\n", d[n][C]);///最終求解的最大價值 ///輸出打印方案 int j = C; for(int i=n; i>0; --i){ if(d[i][j] > d[i-1][j]){ x[i-1] = 1; j = j - V[i-1];///裝入第i-1個寶石後背包能裝入的體積就只剩下j - V[i-1] } } for(int i=0; i<n; ++i) printf("%d ", x[i]);///x[i]==1,即第i+1個放入 printf("\n"); } fclose(stdin); fclose(stdout); return 0; }
5 10
4 9
3 6
5 1
2 4
5 1
4 9
4 20
3 6
4 20
2 4
5 10
2 6
2 3
6 5
5 4
4 6優化
優化:spa
當一個問題找到一個放心可靠的解決方案後, 咱們每每就要考慮一下是否是有優化方案了。
該算法的時間複雜度是O(nC), 即時間都花在兩個for循環裏了,這個應該是沒辦法再優化了。
再看看空間複雜度, 數組d用來保存每一個狀態的值,空間複雜度爲O(nC);
數組V和W用來保存每一個寶石的體積和價值,空間複雜度爲O(n)。
程序總的空間複雜度爲 O(nC),這個是能夠進一步優化的。
首先,咱們先把數組V和W去掉, 由於它們沒有保存的必要,改成一邊讀入一邊計算:.net
int v=0,w=0; for(int i=0; i<=n; ++i){ if(i>0) scanf("%d%d",&v,&w); for(int j=0; j<=C; ++j){ d[i][j] = i==0 ? 0 : d[i-1][j]; if(i>0 && j>=v) d[i][j] =max(d[i-1][j],d[i-1][j-v]+w); } } printf("%d\n", d[n][C]);///最終求解的最大價值
空間優化2,空間複雜度僅爲O(C)
code
#include<cstdio> #include "cstdlib" #include "cstring" using namespace std; #define MAXN 1000 #define MAXC 100000 int main(){ freopen("data.in", "r", stdin);///重定向輸入流 freopen("data.out", "w", stdout);///重定向輸出流 int n, C; while(scanf("%d %d", &n, &C) != EOF){ int* d = (int*)malloc((C+1)*sizeof(int)); memset(d, 0, (C+1)*sizeof(int)); int v=0,w=0; for(int i=0; i<=n; ++i){ if(i>0) scanf("%d%d",&v,&w); for(int j=C; j>=0; j--){ if(i>0 && j>=v) d[j] =max(d[j],d[j-v]+w); } } printf("%d\n", d[C]);///最終求解的最大價值 } fclose(stdin); fclose(stdout); return 0; }