先给出题目吧
通天之分组背包
题目背景
直达通天路·小 A 历险记第二篇
题目描述
自 \(01\) 背包问世之后,小 A 对此深感兴趣。一天,小 A 去远游,却发现他的背包不同于 \(01\) 背包,他的物品大致可分为 \(k\) 组,每组中的物品相互冲突,现在,他想知道最大的利用价值是多少。
输入格式
两个数 \(m,n\),表示一共有 \(n\) 件物品,总重量为 \(m\)。
接下来 \(n\) 行,每行 \(3\) 个数 \(a_i,b_i,c_i\),表示物品的重量,利用价值,所属组数。
输出格式
一个数,最大的利用价值。
样例 #1
样例输入 #1
45 3
10 10 1
10 5 1
50 400 2
样例输出 #1
10
提示
\(0 \leq m \leq 1000\),\(1 \leq n \leq 1000\),\(1\leq k\leq 100\),\(a_i, b_i, c_i\) 在 int
范围内。
这是多重背包的模板题
大意是:给你一个n组物品,每组选一个物品,放入背包,最大化价值并输出
首先最基本的输入数据
我们定义sum[i]表示第i组物品的数量,v[i][j]即第i组物品第j个物品的重量,w同理为价值
其次关于状态的思考
dp如何定义
我们定义dp[i][j]表示前i组物品,背包容量为j时的最大价值
根据0/1背包,我们很容易发现两者dp一样的
同理外层循环亦是一样的
for(int i=1;i<=n;i++) for(int j=0;j<=m;j++)
接下来我们考虑第三层
第三层应该是物品的循环
即 for(int k=1;k<=sum[i];k++)
如何进行状态转移
对于dp[i][j]我们发现,这个物品要么选要么不选,和0/1背包一样
但只能选一个
dp[i][j] = max(dp[i][j],dp[i-1][j-v[i][k]]+w[i][k]);
这是状态转移方程
解释该方程
首先dp[i][j]为不取的情况。
i不用-1是因为dp[i][j]同样是一组内其他物品所计算的最大价值(公用的),不选就是把这个dp给其他物品的最大价值。
后面那个就不用解释了吧!