首页 > 其他分享 >背包问题

背包问题

时间:2023-05-24 18:45:51浏览次数:28  
标签:背包 int d% namespace 问题 物品 价值

Part1 01背包

每种物品只有一个,只能选或不选

表示

u[i][j] 表示容量为j时,前i个物品总价值的最大值,u[i][j]即为答案
v[i] 表示第i个物品的价值
w[i] 表示第i个物品的体积

初始化

当容量为0时,价值总和为0,即

u[i][0] = 0;

当选择0个物品时,价值总和为0,即

u[0][j] = 0;

递归式

\[u[i][j] = max(u[i-1][j], u[i-1][j-w[i]] + v[i]); \]

当选择第 \(i\) 个物品时,应在第 \(i-1\) 个物品的基础上加上第 \(i\) 个物品的价值,容量应满足 \(j-w[i] > 0\)

当不选择第 \(i\) 个物品时,总价值即为第 \(i-1\) 个物品的总价值

当 \(j-w[i] < 0\) 时,背包容量不足,不能选择第 \(i\) 个物品

例题

Acwing 2. 01背包问题

Code

#include <bits/stdc++.h>

using namespace std;

const int N = 1005;

int n, m;
int u[N][N], v[N], w[N];

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%d%d", &w[i], &v[i]);
	for (int i = 1; i <= n; i++) {
		for (int j = m; j >= 1; j--) {
			if (j < w[i]) u[i][j] = u[i-1][j];
			else u[i][j] = max(u[i-1][j], u[i-1][j-w[i]] + v[i]);
		}
	}
	printf("%d", u[n][m]);
	return 0;
}

Part1.2 01背包 - 滚动数组优化

由递推式不难发现,\(i\) 可以省略,即转化为一维数组,\(j\) 的取值简化为 \(m - w[i]\)

递推式

u[j] = max(u[j], u[j-w[i]] + v[i]);

Code

#include <bits/stdc++.h>

using namespace std;

const int N = 1005;

int n, m;
int u[N], v[N], w[N];

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%d%d", &w[i], &v[i]);
	for (int i = 1; i <= n; i++) {
		for (int j = m; j >= w[i]; j--) {
			u[j] = max(u[j], u[j-w[i]] + v[i]);
		}
	}
	printf("%d", u[m]);
}

Part2 完全背包

每种物品有无限个

表示

u[i][j] 表示容量为j时,前i个物品总价值的最大值,u[i][j]即为答案
v[i] 表示第i个物品的价值
w[i] 表示第i个物品的体积

初始化

当容量为0时,价值总和为0,即

u[i][0] = 0;

当选择0个物品时,价值总和为0,即

u[0][j] = 0;

递归式

\[u[i][j] = max(u[i-1][j], u[i-1][j-k*w[i]] + k * v[i]); \]

当选 \(0\) 个第 \(i\) 种物品时,价值为 \(u[i][j] = u[i-1][j];\)

当选 \(1\) 个第 \(i\) 种物品时,价值为 \(u[i][j] = u[i-1][j-w[i]] + v[i];\)

当选 \(2\) 个第 \(i\) 种物品时,价值为 \(u[i][j] = u[i-1][j-2 * w[i]] + 2 * v[i];\)

当选 \(k\) 个第 \(i\) 种物品时,价值为 \(u[i][j] = u[i-1][j-k * w[i]] + k * v[i];\)
\((\) \(0\) \(\leq\) \(k\) \(\leq\) \(\lfloor\) \(\frac {j}{w[i]}\) \(\rfloor\) \()\)

Code

#include <bits/stdc++.h>

using namespace std;

const int N = 1005;

int n, m, u[N][N], w[N], v[N];

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%d%d", &w[i], &v[i]);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            int t = j / w[i];
            for (int k = 0; k <= t; k++) {
                u[i][j] = max(u[i][j], u[i-1][j-k*w[i]] + k * v[i]);
            }
        }
    }
    printf("%d", u[n][m]);
    return 0;
}

Part2.2 滚动数组优化

Code

#include <bits/stdc++.h>

using namespace std;

const int N = 1005;

int n, m;
int u[N], v[N], w[N];

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		for (int j = w[i]; j <= m; j++) {
			u[j] = max(u[j], u[j-w[i]] + v[i]);
		}
	}
	printf("%d", u[m]);
	return 0;
}

Part3 多重背包

Acwing 4. 多重背包问题 I

表示

u[i][j] 表示容量为j时,前i个物品总价值的最大值,u[i][j]即为答案
v[i] 表示第i个物品的价值
w[i] 表示第i个物品的体积
s[i] 表示第i个物品的数量

初始化

当容量为0时,价值总和为0,即

u[i][0] = 0;

当选择0个物品时,价值总和为0,即

u[0][j] = 0;

递推式

由完全背包解法可得,选择物品个数为 $t = $ \(\lfloor\) \(\frac {j}{w[i]}\) \(\rfloor\)
由01背包解法可得,选择物品个数为 $t = $ \(min\) \((\) $1, $ \(\lfloor\) \(\frac {j}{w[i]}\) \(\rfloor\) \()\)
所以多重背包递推式为

\[u[i][j] = min(s[i], j/w[i]); \]

Code

对于完全背包解法进行些许修改即可

#include <bits/stdc++.h>

using namespace std;

const int N = 1005;

int n, m;
int u[N][N], v[N], w[N], s[N];

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%d%d%d", &w[i], &v[i], &s[i]);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			int t = min(s[i], j/w[i]);
			for (int k = 0; k <= t; k++) {
				u[i][j] = max(u[i][j], u[i-1][j-k*w[i]] + k * v[i]);
			}
		}
	}
	printf("%d", u[n][m]);
	return 0;
}

标签:背包,int,d%,namespace,问题,物品,价值
From: https://www.cnblogs.com/Gery-blog/p/17429220.html

相关文章

  • AMD Vitis 调试时,BSP代码的某些行没有被执行,代码乱跳等问题。
    问题AMDVitis调试代码时,BSP代码的某些应该被执行的行,没有被执行,调试器显示代码乱跳等。原因为了提高运行速度,BSP编译时,默认使用了优化选项进行编译,导致调试器对应二进制代码、和C代码时出现问题,显示出错误的执行流程。这只是显示问题,实际执行流程是没有问题的。解决办法将......
  • ANR问题一般分析流程
    ANR问题成因类别 分析步骤确认友商如果是三方应用的anr问题且必现问题或高概率发生,先确认pixel原生机是否可以同样复现,以及友商手机可否复现,分为4种情况。如果判断为三方应用的问题,可转三方质量商务处理并适当贴一些原因分析。三方应用情况分类 我司原......
  • WPF 使用Background="Transparent"+AllowsTransparency="True"实现穿透效果,窗体多次渲
    如果在WPF中的窗体使用AllowsTransparency="True"实现穿透效果,那么该窗体如果移动、快速渲染、控件比较多的情况,会出现卡顿,CPU暴涨的问题。基于以上情况,可以使用另一种方式实现,由@wuty@terryK指导:usingSystem.Windows;usingAnnotation.Business;namespaceDemo{//......
  • 千万级的数据用hashmap存储需要考虑哪些问题?
    答案:一般会预先初始化一个大容量的map解释hashmap默认初始化容量为16,在不断添加key-value时,使用率达到75%会触发扩容,此时hashmap容量会增大一倍,同时会进行key-value的拷贝及重新计算hash映射,当map中存储的key-value越来越多时扩容将导致内存溢出,所以要存储上百万或千万数据时一......
  • 执行sh文件遇到的问题
    1、/bin/bash^M坏的解释器:没有那个文件或目录执行如下命令可解决:sed-i's/\r$//'your_script.sh......
  • Element 表格固定列横向滚动条无法拖动的问题解决
    在Element-UI中,当对表格列进行固定后,底部的横向滚动条就无法拖动了,主要的问题就是固定区域盖住了横向滚动条。方案一:修改el-table__body-wrapper样式的层级,随便设个层级就可::v-deep.el-table__body-wrapper{z-index:2}//加了fixed之后失效::v-deep.el-table__fi......
  • k8s中 fpm 和 nginx 的文件共享问题
    目录引言docker镜像构建哲学为什么一定要共享文件代码的迭代更新问题引言初看这是一个值得记录的问题吗?或者说这算是一个问题吗?各种数据卷挂载,然后一顿操作不就完成了么?我也是这么认为的。看人讨论fpm与nginx的文件共享问题。想到自己当初也遇到了类似的困惑,记得当......
  • 达梦数据库cpu使用占用率过高问题处理
    用户反馈数据库服务器cpu使用率一直很高。整个服务器8个cpu,达梦数据库进程占用5个cpu,如下所示查看数据库会话连接数SELECTSF_GET_PARA_STRING_VALUE(1,'INSTANCE_NAME')AS实例名,STATEAS状态,CLNT_IPAS连接IP,COUNT(*)AS数量FROMV$SESSIONSGROUPBYSTATE,CLNT_IP......
  • 记录一下springboot配置filter之后后端获取不到Authorization问题
    fitler中的添加headers是用逗号隔开的,如content-type,Authorization .......原先代码:res.addHeader("Access-Control-Allow-Headers","content-type");修改后:res.addHeader("Access-Control-Allow-Headers","content-type,Authorization");......
  • 存钱问题
    #include<iostream>#include<cmath>usingnamespacestd;intmain(void){inta1,a2,a3,a4,a5,n1,n2,n3,n4,n5;floatmaxm=0,tem;for(a5=0;a5<3;a5++)for(a4=0;a4<(20-a5*8)/5;a4++)for(a3=0;a3<(20-a5*8-a4*5)/3;a3++)for(a2=0;a2<(20......