首页 > 其他分享 >DP背包-完全背包

DP背包-完全背包

时间:2023-10-04 17:01:50浏览次数:42  
标签:背包 int text 完全 DP 草药 转移 dp

背包问题-完全背包

例题

题目描述

此题和原题的不同点:

\(1\). 每种草药可以无限制地疯狂采摘。

\(2\). 药的种类眼花缭乱,采药时间好长好长啊!师傅等得菊花都谢了!

输入格式

输入第一行有两个整数,分别代表总共能够用来采药的时间 \(t\) 和代表山洞里的草药的数目 \(m\)。

第 \(2\) 到第 \((m + 1)\) 行,每行两个整数,第 \((i + 1)\) 行的整数 \(a_i, b_i\) 分别表示采摘第 \(i\) 种草药的时间和该草药的价值。

输出格式

输出一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

完全背包模型与 \(\text{0-1}\) 背包类似,与 \(\text{0-1}\) 背包的区别仅在于一个物品可以选取无限次,而非仅能选取一次。

我们可以借鉴 \(\text{0-1}\) 背包的思路,进行状态定义:设 \(dp_{i,j}\) 为只能选前 i 个物品时,容量为 j 的背包可以达到的最大价值。

需要注意的是,虽然定义与 \(\text{0-1}\) 背包类似,但是其状态转移方程与 \(\text{0-1}\) 背包并不相同。

思路

可以考虑一个最暴力的做法:对于第 \(i\) 件物品,枚举其选了多少个来转移。这样做的时间复杂度是 \(\text{O(n^3)}\) 的(肯定爆炸)。

状态转移方程如下:
\(dp_{i,j}=\max_{k=0} ^{+\infty }(dp_{i-1,j-k\times w_i}+v_i\times k)\)

考虑做一个简单的优化。可以发现,对于 \(dp_{i,j}\),只要通过 \(dp_{i,j-w_i}\) 转移就可以了。因此状态转移方程为:

\(dp_{i,j}=\max(dp_{i-1,j},dp_{i,j-w_i}+v_i)\)

理由是当我们这样转移时,\(dp_{i,j-w_i}\) 已经由 \(dp_{i,j-2\times w_i}\) 更新过,那么 \(dp_{i,j-w_i}\) 就是充分考虑了第 \(i\) 件物品所选次数后得到的最优结果。换言之,我们通过局部最优子结构的性质重复使用了之前的枚举过程,优化了枚举的复杂度。

代码如下

#include <iostream>
using namespace std;
const int maxn = 1e4 + 5;
const int maxW = 1e7 + 5;
int n, W, w[maxn], v[maxn];
long long f[maxW];

int main() {
  cin >> W >> n;
  for (int i = 1; i <= n; i++) cin >> w[i] >> v[i];
  for (int i = 1; i <= n; i++)
    for (int l = w[i]; l <= W; l++)
      if (f[l - w[i]] + v[i] > f[l]) f[l] = f[l - w[i]] + v[i];  // 核心状态方程
  cout << f[W];
  return 0;
}

标签:背包,int,text,完全,DP,草药,转移,dp
From: https://www.cnblogs.com/2509-SYM/p/17742458.html

相关文章

  • DP背包-01背包
    背包问题-01背包首先我们要明白什么是01背包,在下述例题中,由于每个物体只有两种可能的状态(取与不取),对应二进制中的\(0\)和\(1\),这类问题便被称为\(\text{「0-1背包问题」}\)。题目描述有\(N\)件物品和一个容量为\(M\)的背包。第\(i\)件物品的重量是\(W_i\),价值是\(D......
  • 【做题笔记】dp,但是国庆限定版
    Day1方块消除传送门看到这个数据范围就可以猜测正解是\(O(n^4)\)的dp,与这个差不多相符合的可以想到区间dp。然后大胆猜测一下就是区间dp,令\(dp[i][j]\)表示消除掉\([i,j]\)后的最大价值,这个显然可以从长度更短的区间转移过来。所以此题我们可以从区间dp的方向思考......
  • 高维前缀和 (SOSDP)
    介绍一维前缀和:$s[i]=s[i-1]+a[i]$二维前缀和:$s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]$当然也可以这么写:for(inti=1;i<=n;i++)for(intj=1;j<=n;j++)a[i][j]+=a[i-1][j];for(inti=1;i<=n;i++)for......
  • 10.4 国庆 环形dp与基环树笔记
    1.知识点环形dp环形dp的概念•环形dp与基环树在许多环形结构的问题中,我们可以在环中从某个位置把环断开,把这个环变成线性的,然后进行\(dp\)等操作。•把能通过上述操作解决的环形问题称作"可拆解的环形问题"。环形dp的两种策略•第一次在任意位置把环断开成链,按照......
  • DP 总结
    最小包含串模型描述给定两个长度分别为\(n,m\)字符串\(s,t\),求出长度最小的串,使两个串都是这个串的子序列。基本解法设\(f_{i,j}\)表示第一个字符串前\(i\)个和第二个字符串前\(j\)个字符的最短包含串长度。边界:\(f_{i,0}=f_{0,i}=i\)。转移:\[f_{i,j}=\begin{ca......
  • 状态机DP,力扣188. 买卖股票的最佳时机 IV
    状态机DP,力扣188.买卖股票的最佳时机IV整数数组prices和一个整数k,其中prices[i]是某支给定的股票在第i天的价格。一次只能参与一笔交易,最多可以进行k笔交易,求最大利润。确定状态f[n+1][k+2][2],f[i][j][0]、f[i][j][1]分别表示前i天最多进行j次交易,且在第i天时......
  • dpdk 编译
     引用: https://zhuanlan.zhihu.com/p/56670068720.11版本 DPDK(DataPlaneDevelopmentKit)是数据平面开发工具包,由用于加速在各种CPU架构上运行的数据包处理的库组成。DPDK需要一定的网卡硬件支持,以Intel为例,支持以下网卡: 下面带大家过一遍编译流程,扫清后续应用的......
  • 重学OI#4 简单dp
    观前须知:本文顺序较为混乱,根据本人复习顺序写的,难度严格不递增dp不像数据结构可以套路性的将,以例题为主吧part1:树形dp树是一种非常好的结构,其天然的递归形态保证了最优子结构,使得dp有很好的发挥空间一般状态与子树和路径有关,也有时扯到叶子节点,所以不套路化,特殊情况可能会......
  • RDP远程登录后全屏,本地的任务栏始终显示的问题解决
    文章目录问题解决参考问题RDP远程登录后全屏,本地的任务栏(TaskBar)始终在下面,遮住了远程桌面的最下面,进行了解决。解决BestsolutionhowtohidelocalTaskbarwhenRDPtoaremotedesktopLaunchTaskManagerRight-click“WindowsExplorer”Select“Restart”Itworkson......
  • csps区间dp
    加分二叉树我们可以枚举中间这个k的位置,然后分别递归计算左右子树,这就让我们想到这是一个和区间有关的,我们可以用区间dp来解决。\(f[i][j]\)表示i,j这个区间的最大分值。用一个很板子的区间dp就可以解决了。至于求前序遍历,我们也只需要通过递归然后枚举中间的根,第一个满足......