1
使用动态规划,dp[i][j]存储:到第i个物品时,空间大小为j的情况下的最大价值
转移方程是:dp[i][j] = max(dp[i-1][j],dp[i-1][j - weight[i]] + value[i])
时间复杂度是O(NV),N为物品的个数,V为最大容量,空间复杂度为O(NV)
#include<iostream> using namespace std; const int N = 5; const int volumn = 1000; int dp[N + 1][volumn + 1]; const int value[N+1] = {0,8,10,4,5,5};//下标从1开始 const int weight[N+1] = {0,600,400,200,200,300};//下标从1开始 void dp_01() { for(int i = 1; i <= N; i++) for(int j = 1; j <= volumn; j++) { if(j >= weight[i]) dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]); else dp[i][j] = dp[i-1][j]; } cout << dp[N][volumn]<<endl; } int main() { dp_01(); return 0; }
2 简化空间复杂度的01背包解法:
使用一维空间f[volumn+1],来替代dp[][]。
View Code
#include<stdio.h> #include<iostream> #include<limits.h> using namespace std; const int T = 5; const int V = 10; int f[V + 1]; int W[T] = {8,10,4,5,5}; int C[T] = {6,4,2,2,3}; int max(const int& a, const int& b) { return a >= b ? a:b; } void package() { freopen("out.txt","w",stdout); //init for(int i = 1; i <= V; i++) { f[i] = INT_MIN;//必须装满的情况 //f[i] = 0;//可以不装满的情况 } f[0] = 0; for(int i = 0; i < T; i ++) { for(int v = V; v >= C[i]; v--) { f[v] = max(f[v-C[i]] + W[i],f[v]); } } cout << f[V] << endl; } int main() { package(); return 0; }
记录每天的收获,from now on!