标签:
70 3 71 100 69 1 1 2
3
我从学DP 到现在已经过去两个月了,现在唯一就是知道DP是动态规划,剩下就咸鱼了。所以我决定复习DP,写写DP的题。
来说一说今天的主题:背包问题。
背包问题最开始是这样的:
现在你有一个容量有限制的背包,还有许多有体积和价值的物品,物品的体积和价值各不相同。而背包问题问的就是在限定的体积下,你最多能装多大价值的物品。
基本上裸的背包题都是这个套路,当然价值可以变成时间什么的,像“采药”这道题,背包就是有限的时间,而价值就是采一种药的时间(多写写背包问题就能明显发现一道题是不是背包)。
好了,开始上课。
首先,给出背包问题的模板
#include <bits/stdc++.h> using namespace std; const int maxn = 102, maxT = 1005; int f[maxn][maxT]; //i个物品选择一些物品, 总体积为j int main() { int T, n; cin >> T >> n; for (int i = 1; i <= n; ++i) { int V, C; cin >> V >> C; for (int j = 0; j <= T; ++j) f[i][j] = f[i - 1][j]; //不选这个物品 for (int j = 0; j + V <= T; ++j) //选这个物品 if ((f[i][j + V]) < (f[i - 1][j] + C)) (f[i][j + V]) = (f[i - 1][j] + C); } cout << f[n][T] << endl; }
能看懂的就可以跳过下面的部分然后去A题了,没看懂的不要着急,我会慢慢讲。
先解释一下各变量和数组都是干什么的。
f[i][j]表示背包容量为j时选了i件物品的最大价值,T,n分别表示背包容量,物品件数,V C就是每件物品的体积和价值。
每输入一组数据,就将状态更新一次,代码的注释也写得很清楚,我们的策略是默认先不选择这个物品,所以f[i][j] = f[i - 1][j]是将当前状态记为和之前一样的状态,就相当于没有选择这个物品;而在更新的时候我们判断只要装入它不超容量,并且价值比原价值大的话,就装入它。
P.S.这是一道极其典型的背包问题,是最基础的背包问题,因为状态只有“0”和“1”(不装和装)两种,所以被称作“01背包”。
【OpenJudge 2.6-1775】讲一讲背包问题(一)【背包DP】
标签:
原文地址:http://www.cnblogs.com/Kotori-Minami/p/5976844.html