Knapsack problem (Knapsack Problem)
Problem Description
A traveler carrying a backpack, items can be placed in the backpack there are n, weight and value of each item are wi, vi. If the backpack maximum weight limit is b, each of a plurality of articles can be put. How to choose the items into the backpack so that the maximum value of the backpack? Located above wi, vi, b are positive integers.
Modeling problems
Solution is <x1, x2, ..., xn >, where xi is the i-th number of articles into the backpack.
Linear Programming: of constrained condition by taking the maximum or minimum linear problem.
Integer programming problem: xi-variable linear programming problems are non-negative integers.
Subproblem defined and calculated sequence
Subproblem defined: defined by the parameters k and Y
k: Consider, 2, ..., k selection of items 1.
y: the total weight of the backpack is not more than y.
Original Input: k = n, y = b .
Subproblems calculation order: k = 1,2, ..., n for a given k, y = 1, 2, ..., b.
Recursive function optimization equation
Fk (y): pre-k kinds of goods loaded, gross weight does not exceed y, the maximum value of the backpack to achieve.
Mark function
ik (y): pre-k kinds of goods loaded, gross weight does not exceed y, backpack achieve maximum value Max sign into fashion items
Examples
Tracking Solution
time complexity
Nb memo item to be calculated, each constant time, the calculation time is O (nb).
Code examples
Description Title:
there are N items V and a capacity of the backpack. Value of i-th items that C [i], a weight W [i]. Solving the items into a backpack which allows the maximum value of the sum.
Input Description:
input of the first number of rows NV (1 <= N <= 500) (1 <= V <= 10000)
input N numbers represent two line CW (1 <= C <= 50000, 1 <= W <= 10000)
Examples
输入
5 10
8 6
10 4
4 2
5 4
5 3
输出
19
Code
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int N,V;
while(cin >> N >> V)
{
vector<int> value(N);//存储每个物品的价值
vector<int> capacity(N);//存储每个物品的容量
for(int i = 0; i < N; ++i)
{
cin >> value[i] >> capacity[i];
}
vector<vector<int>> dp(N+1,vector<int>(V+1,0));
//有N+1行,但是从1开始遍历,所以每行表示每个物品
//有V+1列,但是从1开始遍历,所以每列表示从1开始到最大容量 的 各种情况下 的 物品最大价值存储
for(int i = 1; i < N+1; ++i)
{
for(int j = 1; j < V+1; ++j)
{
if(capacity[i-1] > j)//如果不下,那就等于上次的最优存储
{//这里的capacity[i-1]是因为这里的i从1开始
dp[i][j] = dp[i-1][j];
}
else//如果能放下,有两种情况:1、放 2、不放
//放和不放取决于放了之后是否是最优的,于是创建一个临时变量。
{//dp[i-1][j-capacity[i-1]]:i-1:上面一行,j-capacity[i-1]:装了i-1这个物品之后还剩的容量。
//所以整体就是:当前的tmp_best == 装了i-1物品的价值 + 装了这个物品后剩余的容量还可以装的最优的方案
int tmp_best = value[i-1] + dp[i-1][j-capacity[i-1]];
dp[i][j] = max(tmp_best,dp[i-1][j]);
}
}
}
//返回最后一个元素就是最优的方案
cout << dp[N][V] << endl;
}
return 0;
}