专栏文章

题解:P1782 旅行商的背包

P1782题解参与者 6已保存评论 6

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
6 条
当前快照
1 份
快照标识符
@miookduo
此快照首次捕获于
2025/12/02 22:35
3 个月前
此快照最后确认于
2025/12/02 22:35
3 个月前
查看原文

思路

将这道题分为两个部分。

第一部分

给你 nn 类物品。每种价值 ViV_i,体积为 WiW_i,数量为 DiD_i,背包体积为 CC 的最大价值。
注意:题目中价值为 WiW_i,体积为 ViV_i
一眼多重背包,在一眼时间复杂度不难想到二进制优化。
不会二进制优化的可以先去做 宝物筛选
也可自行理解。

代码

CPP
for (int i = 1; i <= n; i++)
{
  int W=read(),V=read(),D=read();
  for (int j = 1; j <= D; j*=2)
  {
    v[++cnt]=V*j;
    w[cnt]=W*j;
    D-=j;
  }
  if (D)
  {
    v[++cnt]=V*D;
    w[cnt]=W*D;
  }
}
for (int i = 1; i <= cnt; i++)
{
  for (int j = C; j >= w[i]; j--)
  {
    dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
  }
}

第二部分

看到 m5m \le 5 不难想到可以直接枚举。
对于每个物品运用前面的 dpdp 继续计算。
注意 dpdp 的无后效性,所以要从后往前,先枚举大小再枚举个数。

代码

CPP
for (int i = 1; i <= m; i++)
{
  int a=read(),b=read(),c=read();
  for (int x = C; x >= 0; x--)
  {
    int y = a*x*x+b*x+c;
    for (int j = C; j >= x; j--)
    {
      dp[j]=max(dp[j],dp[j-x]+y);
    }
  }
}
注意:每个物品从 00 个开始枚举。
关键代码已给出,其余代码自行补充。

评论

6 条评论,欢迎与作者交流。

正在加载评论...