ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

背包问题

2022-07-25 23:35:58  阅读:118  来源: 互联网

标签:状态 cnt 背包 int max 问题 dp


背包问题

体面一般是给你n个物品,体积为m的背包,每个物品的体积为v[i],价值w[i],求这个背包可以装的最大价值。

1.dp问题的分析思路。

image-20220722185250914

1.状态表示有表示当前状态下的集合里面某个属性的最优解。属性一般就是最大值,最小值,数量。

2.状态计算就是考虑如何把当前集合划分为更小的子集,然后从前面已经求解的结果计算出来。如背包问题集合划分就是考虑选不选第i个物品。要求对集合的划分不应该漏掉某种情况。

所以动态规划的解题思路应该是先定义状态(状态表示),然后对这个状态所定义集合划分,然后在由集合的性质来从前面已经求解的状态来求解。

1.01背包

这个公式基本上是所有背包的核核心吧,基本都是从他优化来的。f[i] [j]代表的状态时选取i个物品,那状态如何计算呢?那就是选与不选第i个物品。于是就有了下面这个状态转移方程,

$$
f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i])
$$

很明显这个f[i] [j]状态都是从f[i-1]行优化过来。所以他也可以优化从一维的。

$$
f[j]=max(f[j],f[j-v[i]]+w[i])
$$

但是注意这样枚举体积的时候就应该逆序枚举,因为这样我求每一个状态f[i]的时候他前面的都还是没有更新的(也就是前面状态都还是上一行的)。

2.完全背包

完全背包的状态转移方程推导

image-20220722194232644

由这个可以推到完全背包的状态转移方程是

$$
f[i][j]=max(f[i-1][j],f[i][j-v[i]]+w[i]);
$$

他也是可以优化的。很明显f[i] [j]的推导只与他这一行有关系,是从f[i]行转移过来的,所以是转移f[i] [j]时只需要这一行更新的。所以将他化成一维的的时候时需要更新这一行。所以我枚举体积的时候应该顺序枚举。

$$
f[j]=max(f[j],f[j-v[i]]+w[i])
$$

3.多重背包

  1. 二进制优化 (优化成了01背包)

#include<bits/stdc++.h>
using namespace std;
const int N=25000,M=2010;
int n,m;
int v[N],w[N],dp[M];
int main(){
cin>>n>>m;
int cnt=0;
for(int i=1;i<=n;i++){
int a,b,s;
cin>>a>>b>>s;
int k=1;
while(k<=s){
v[++cnt]=a*k;
w[cnt]=b*k;
s-=k;
k*=2;
}
if(s>0){
v[++cnt]=a*s;
w[cnt]=b*s;
}
}
for(int i=1;i<=cnt;i++){
for(int j=m;j>=v[i];j--){
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
cout<<dp[m]<<endl;
return 0;
}

4.分组背包

就是每组只能选一个。

image-20220722203634809

那很明显状态转移就是要么不选这一组,要么就在这一组中选择第k个

$$
f[i][j]=max(f[i-1][j],f[i-1][j-v[i][k]]+w[i][k])
$$

这个复杂度很明显时O(n^3)的。

5.到达型背包

这主要就是看某个状态可不可以到达,比如洛谷的砝码称重,就是看某个状态可不可达。还有音量调节。

一般就是选不选这个物品,但是的注意是都从上一行优化过来的吗?都是从一侧优化过来的吗?

$$
dp[i][j]=dp[i-1][j]||dp[i-1][j-v[i]]
$$

这两个状态有一个是可达的dp[i] [j]就是可达的。

疑问:背包问题对于dp[i]一定使装满的吗?不一定呀,那为什么洛谷p2918可以这样写?不懂

标签:状态,cnt,背包,int,max,问题,dp
来源: https://www.cnblogs.com/silky----player/p/16519243.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有