【SSL】1236逃亡的准备(多重背包)
发布日期:2021-05-07 09:19:25 浏览次数:20 分类:精选文章

本文共 1160 字,大约阅读时间需要 3 分钟。

多重背包问题可以通过将物品数量拆分为二进制形式来解决。每个物品的数量m可以表示为多个二进制位的和,这样每个位对应一个独立的物品块。然后,可以使用动态规划来计算如何选择这些块,使得背包的体积不超过限制且价值最大化。

首先,输入物品种数n和背包体积v。然后,逐个处理每个物品,分解其数量m为二进制形式。例如,如果m=5,可以拆分为4和1,这样每个拆分后的块的体积和价值都乘以相应的数量。将所有物品分解后,使用动态规划来计算如何选择这些块,使得总价值最大。

动态规划的状态转移方程为f[j] = max(f[j], f[j - w[i]] + s[i]),其中j表示当前体积,i表示物品块。遍历所有可能的体积j和每个块i,更新状态。最终,f[v]即为最大价值。

代码实现:

#include 
#include
#include
using namespace std;
long long n, v;
int len = 0;
long long w[64010], s[64010], f[1010];
void input() {
for (long long i = 1; i <= n; ++i) {
long long m, wt, st;
scanf("%lld%lld%lld", &m, &wt, &st);
for (int j = 0; (1 << j) <= m; ++j) {
if (m >= (1 << j)) {
w[len] = wt * (1 << j);
s[len] = st * (1 << j);
m -= (1 << j);
}
}
if (m > 0) break;
}
}
void dp() {
for (int i = 0; i <= len; ++i) {
for (int j = v; j >= 0; --j) {
if (j >= w[i]) {
f[j] = max(f[j], f[j - w[i]] + s[i]);
}
}
}
}
int main() {
input();
dp();
printf("%lld", f[v]);
return 0;
}

输出结果为最大价值总和。

上一篇:【SSL】2293暗黑游戏
下一篇:【SSL】1197质数和分解(normal)

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2025年04月16日 08时58分25秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章