0-1背包(ZeroOnePack): 有N件物品和一个容量为C的背包。(每种物品均只有一件)第i件物品的重量是W[i],价值是V[i]。求解将哪些物品装入背包可使价值总和最大。
特点:每种物品仅有一件,可以选择放或不放。物品重量总和小于或等于背包容量。
*一开始,可以使用暴力方法,遍历所有可能性,再选出符合条件的可能,然后比较找出价值最大的。
运用DP思想解决子问题
设m[ i ] [ j ] :背包容量为j,可选择物品为第 i 到 n 个时的最优值问题分析
分析两种情况:1. 第i个物品放不进去背包:W[ i ] > j;
2.可以放进去,但是可以选择放进去或者不放:W[ i ] =< j;
1 2 3 4
V[] 8 7 4 16
W[] 4 2 3 8
列:第i个到第n个物品;
行:背包容量
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
1 | 0 | 0 | 0 | 0 | 8 | 8 | 8+7 | 8+7 | |||
2 | 0 | 0 | 7 | 7 | 7 | ||||||
3 | 0 | 0 | 0 | 4 | 4 | 8+7, | 8+7+4, | ||||
4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 16 |
#include <iostream>
using namespace std;
int w[105], val[105];
int dp[105][1005];
int main()
{
int t, m, res=-1;
cin >> t >> m;//t:背包容量;m:物品总数
for(int i=1; i<=m; i++)
cin >> w[i] >> val[i];
for(int i=1; i<=m; i++) //物品
for(int j=t; j>=0; j--) //容量
{
if(j >= w[i])
dp[i][j] = max(dp[i-1][j-w[i]]+val[i], dp[i-1][j]);
else
dp[i][j] = dp[i-1][j];
}
cout << dp[m][t] << endl;
return 0;
}