【算法】动态规划之背包DP问题(2024.5.11)

 前言:

本系列是学习了董晓老师所讲的知识点做的笔记

董晓算法的个人空间-董晓算法个人主页-哔哩哔哩视频 (bilibili.com)

动态规划系列 

【算法】动态规划之线性DP问题-CSDN博客

01背包

步骤:

分析容量j与w[i]的关系,然后分析是否要放入背包

二维数组

for(int i=1; i<=n; i++)       //物品
    for(int j=1; j<=m; j++)     //容量
      if(j<w[i]) f[i][j]=f[i-1][j];            
      else f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i]);

一维数组用逆序循环的原因

用一维数组f[i]只记录一行数据,让j值顺序循环,顺序更新f[j]值,f[j-w[i]]会先于f[j]更新,会出错。

如果j是逆序循环,f[j]会先于f[j-w[i]]更新

01背包使用的是上一层的值,如果顺序循环的话就会改变应有的值

for (int i = 1; i <= n; i++)//物品i
{
    for (int j = m; j >= w[i], j--)//容量j
	{
		f[j] = max(f[j], f[j - w[i]] + c[i])
	}
}

  

完全背包 

完全背包使用的是同一层的值,顺序循环的话改变值正是他所需要的,所以他可以顺序循环

for(int i=1; i<=n; i++)       //物品
    for(int j=1; j<=m; j++)     //容量
      if(j<w[i]) f[i][j]=f[i-1][j];            
      else f[i][j]=max(f[i-1][j],f[i][j-w[i]]+c[i]);
for (int i = 1; i <= n; i++)//物品i
{
    for (int j = w[i]; j <= m, j++)//容量j
	{
		f[j] = max(f[j], f[j - w[i]] + c[i])
	}
}

01背包和完全背包的区别

01背包第i件物品可以放入0个或者1个

完全背包第i件物品可以放入0个,1个,2个..... 

多重背包

01背包:第i种物品可以取0件、取1件。

多重背包:第i种物品可以取0件、取1件、取2件……取s件。

多重背包转化为01背包求解:把第i种物品换成s件01背包中的物品,每件物品的体积为k*v,价值为k*w(0≤k≤s)。

朴素算法

  //v[i],&w[i],&s[i])分别表示体积,价值,数量
  for(int i=1; i<=n; i++)               
  for(int j=0; j<=m; j++)               
  for(int k=0; k<=s[i]&&k*v[i]<=j; k++) 
    f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);

二进制优化

int num = 1;
for (int i = 1; i <= n; i++)
{
	cin >> v >> w >> s;//体积,价值,数量
	for (j = 1; j <= s; j <<= 1)
	{
		vv[num] = j * v;
		ww[num++] = j * w;
		s -= j;
	}
	if (s)
	{
		vv[num] = s * v;
		ww[num++] = s * w;
	}
}
for (int i = 1; i < num; i++)
	for (int j = m; j >= v[i]; j--)
		f[j] = max(f[j], f[j - vv[i]] + ww[i]);

单调队列

前置知识 

【算法】用存入下标的方法来巧解单调队列-CSDN博客

 

(k-q[h])/v是还能放入物品的个数。f[k]=窗口中的最大值+还能放入物品的价值。 

混合背包 

题目:

思路

分类处理的思想:
1.利用多重背包的二进制优化,将多重背包转化为多个01背包。
2.用a,b,c三个数组来记录转化之后的所有背包的体积、价值、类型,c[i]==0表示完全背包,c[i]==1表示01背包。最后再做一遍,以c的值分为两类,做完全背包和01背包。

for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", &v, &w, &s);
    if (s == 0) {     //完全背包
        a[num] = v;
        b[num] = w;
        c[num++] = 0; //背包类型 
    }
    else {         
        if (s == -1)
            s = 1;//01背包转多重背包
        int k = 1;
        while (s >= k) {//二进制拆分
            a[num] = k * v;
            b[num] = k * w;
            c[num++] = 1;
            s -= k; k <<= 1;
        }
        if (s) {
            a[num] = s * v;
            b[num] = s * w;
            c[num++] = 1;
        }
    }
}
for (int i = 1; i < num; i++) {
	if (c[i] == 1) //01背包
	     for (int j = m; j >= a[i]; j--)
			f[j] = max(f[j], f[j - a[i]] + b[i]);
	else        //完全背包
		for (int j = a[i]; j <= m; j++)
			f[j] = max(f[j], f[j - a[i]] + b[i]);
}

二维费用背包 

f[i][k]: 背包容量为j,且承重为k时,能放入的最大价值。

f[V][M]: 背包容量为V,且承重为M时能放入的最大价值,即全局最优解。

  cin>>n>>V>>M;
  for(int i=1; i<=n; i++){  //物品 
    cin>>v>>m>>w;
    for(int j=V; j>=v; j--) //体积
    for(int k=M; k>=m; k--) //重量
      f[j][k]=max(f[j][k],f[j-v][k-m]+w);
}
  cout<<f[V][M];

分组背包

分组背包与多重背包的区别是分组背包在每一个组中只能选一个 

决策在前,体积在后的方法是错误的(用同一组的物品来更新了),积前策后才是对的

二维决策:同一个组里面的物品只能选一个

一维决策:个数

for (int i = 1; i <= n; i++)     //物品组
for (int j = 1; j <= V; j++)     //体积
for (int k = 0; k <= s[i]; k++)  //决策
if (j >= v[i][k])
f[i][j] = max(f[i][j], f[i - 1][j - v[i][k]] + w[i][k]);
for (int j = 1; j <= s; j++) 
cin >> v[j] >> w[j];
for (int j = V; j >= 1; j--) //体积
for (int k = 0; k <= s; k++) //决策
if (j >= v[k]) f[j] = max(f[j], f[j - v[k]] + w[k]);

相关推荐

  1. 算法专题】动态规划简单多状态 dp 问题

    2024-05-12 08:20:11       30 阅读
  2. 算法动态规划dp问题),持续更新

    2024-05-12 08:20:11       41 阅读
  3. 动态规划算法解决背包问题(Python)

    2024-05-12 08:20:11       39 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-12 08:20:11       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-12 08:20:11       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-12 08:20:11       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-12 08:20:11       20 阅读

热门阅读

  1. HarmonyOS应用开发者高级认证 试题+答案

    2024-05-12 08:20:11       15 阅读
  2. 1-k8s常见注意事项

    2024-05-12 08:20:11       9 阅读
  3. KubeKey 部署 K8s v1.28.8 实战

    2024-05-12 08:20:11       14 阅读
  4. 从零开始精通RTSP之传输AAC音频流

    2024-05-12 08:20:11       12 阅读
  5. 【GitHub】将本地VueCLI项目关联到GitHub远程仓库

    2024-05-12 08:20:11       13 阅读
  6. Vue3实战笔记(07)— Axios进阶与提高

    2024-05-12 08:20:11       11 阅读
  7. Flink面试整理-Flink的监控和日志收集

    2024-05-12 08:20:11       14 阅读