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

背包问题

时间:2023-07-10 09:12:01浏览次数:24  
标签:背包 int max cin 问题 01 using

本文默认 \(w_i\) 为重量,\(d_i\) 为价值,\(m_i\) 为数量


01背包

例题:P2871 [USACO07DEC] Charm Bracelet S

题目:

image

思路:

设 \(f_{i, j}\) 表示选到第 \(i\) 个物品,占用空间为 \(j\)可以获得的最大价值。

有 \(f_{i, j} = \max(f_{i - 1, j}, f_{i - 1, j - w[i]} + d[i])\)。

优化可得 \(f[j] = \max(f[j], f[j - w[i]] + d[i])\)。

注意:\(j\) 递归时一定要倒着来。

代码:
#include <bits/stdc++.h>

using namespace std;

const int N = 3500, M = 13000;

int n, m;
int w[N], d[N];
int f[M];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> w[i] >> d[i];
	
	for (int i = 1; i <= n; i++) {
		for (int j = m; j >= w[i]; j--) {
			f[j] = max(f[j], f[j - w[i]] + d[i]);
		}
	}
	cout << f[m] << '\n';
	return 0;
}

完全背包

例题:P1616 疯狂的采药

题目:

image

思路:

完全背包中物体可以被选无数次,而01背包每个物体只能选一次。

设 \(f_{i, j}\) 表示选到第 \(i\) 个物品,占用空间为 \(j\) 可以获得的最大价值。

有 \(f_{i, j} = \max(f_{i - 1, j}, f_{i - 1, j - w[i] \times k} + d[i] \times k)\)。

\(k\) 表示选取物体的数量。

优化可得 \(f[j] = \max(f[j], f[j - w[i]] + d[i])\)。

注意:\(j\) 递归时一定要正着来,与01背包相反。

代码:
#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

const int N = 10010, M = 10000010;

int n, m;
int w[N], d[N];
i64 f[M];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	cin >> m >> n;
	for (int i = 1; i <= n; i++) cin >> w[i] >> d[i];
	
	for (int i = 1; i <= n; i++) {
		for (int j = w[i]; j <= m; j++) {
			f[j] = max(f[j], f[j - w[i]] + d[i]);
		}
	}
	cout << f[m] << '\n';
	return 0;
}

分组背包

例题:P1776 宝物筛选

题目:

image

思路:

完全背包中物体可以被选无数次,而分组背包每个物体有次数限制。

设 \(f_{i, j}\) 表示选到第 \(i\) 个物品,占用空间为 \(j\) 可以获得的最大价值。

有 \(f_{i, j} = \max(f_{i - 1, j}, f_{i - 1, j - w[i] \times k} + d[i] \times k)\)。

\(k\) 表示选取物体的数量,但其有次数限制。


二进制优化:

  1. 如果物品 \(i\) 个数 \(m_i\) 乘以重量 \(w_i\),那么该物品可以按照完全背包的做法来做;

  2. 将次数 \(m_i\) 分成 \(1 + 2 + 4 + 2^n + k\),那么 \(1\sim m_i\) 的每个数字都可以被表示出来,那么这些可以被看作一个个整体,可以按照01背包来做。


代码:
#include <bits/stdc++.h>

using namespace std;

const int N = 110, W = 40010;

int n, g;
int f[W];
int v[N], w[N], m[N];

void solve() {
	for (int i = 1; i <= n; i++) {
		if (w[i] * m[i] >= g) {
			for (int j = w[i]; j <= g; j++) {
				f[j] = max(f[j], f[j - w[i]] + v[i]);
			}
		}
		else {
			for (int k = 1; m[i]; k <<= 1) {
				int use = min(k, m[i]);
				for (int j = g; j >= w[i] * use; j--) {
					f[j] = max(f[j], f[j - w[i] * use] + v[i] * use);
				}
				m[i] -= use;
			}
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	cin >> n >> g;
	for (int i = 1; i <= n; i++) cin >> v[i] >> w[i] >> m[i];
	solve();
	
	cout << f[g] << '\n';
	return 0;
}

分组背包

image

例题:P1757 通天之分组背包

题目:

image

思路:

对组里的每一个物体按照01背包的方式处理,

注意三层循环的顺序,

否则有可能会多选。

代码:
#include <bits/stdc++.h>

using namespace std;

const int N = 1010, M = 1010;

int n, m, s;
int f[M];
int a[N][N], b[N][N], cnt[N];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> m >> n;
    for (int i = 1; i <= n; i++) {
        int x, y, z;
        cin >> x >> y >> z;
        s = max(s, z);
        cnt[z]++;
        a[z][cnt[z]] = x, b[z][cnt[z]] = y;
    }

    for (int i = 1; i <= s; i++) {
        for (int k = m; k >= 0; k--) {
            for (int j = 1; j <= cnt[i]; j++) {
                if (k < a[i][j]) continue;
                f[k] = max(f[k], f[k - a[i][j]] + b[i][j]);
            }
        }
    }

    cout << f[m] << '\n';
    return 0;
}

有依赖的背包

参见我的博客

标签:背包,int,max,cin,问题,01,using
From: https://www.cnblogs.com/PlayWithCPP/p/17537301.html

相关文章

  • 麒麟V10操作系统安装达梦DM8常见问题分享
    一、麒麟V10关闭防火墙kylinV10系统或linux系统关闭启动防火墙开启防火墙并设置开机自启启动:systemctlstartfirewalld关闭:systemctlstopfirewalld查看状态:systemctlstatusfirewalld开机禁用:systemctldisablefirewalld开机启用:systemctlenablefirewalld二、......
  • Django中migrate 出现问题
    问题:不小心删掉了数据库中的表格,重新迁移时出现如下问题 解决办法:1.在数据库中新建dashboard_piechart表2.运行pymanage.pymigratedashboardzero3.运行pymanage.pymigratedashboard查看数据库,新建了Model中的表格......
  • CSS_相关问题及解决_持续更新
    css_margin塌陷问题问题描述<divclass="father"><divclass="child1"></div><divclass="child2"></div></div>当child1设置了margin-top时,margin-top会作用在father上当child2设置了margin——bottom时,margin-b......
  • Seata-server.bat闪退问题解决及Seata快速搭建
    转:Seata-server.bat闪退问题解决及Seata快速搭建 1.4上 部署的话 参考下边的地址:seata部署指南(v1.6.1) 启动seata服务前请先做好配置 ......
  • 转运的运输问题——Python实现(二)
    运筹学经常用于解决现实生活中的复杂问题,特别是改善或优化现有系统的效率。研究运筹学的基础知识包括实分析、矩阵论、随机过程、离散数学和算法基础等。而在应用方面,多与仓储、物流、算法等领域相关。因此运筹学与应用数学、工业工程、计算机科学、经济管理等相关专业。运筹学中......
  • 相较于Scrum, 我更推崇精益Kanban,帮助团队建立价值交付流,识别瓶颈问题
    最近在学习实践精益Kanban方法,结合自己团队实践Srum的经历,整理些资料二者的差异。相较于Scrum,我更推崇精益Kaban。Agile是一套理论和原则,就像天边的北极星。Devops是一种软件开发和运维团队间自动化和集成过程的方法。当实现Agile和Devops方法时,Kanban和Scrum提供了管理这些......
  • 前端解决跨域问题
    1.JSONP 缺点是只能解决get请求不支持postJSONP原理就是通过script标签的src属性请求跨域的数据接口并通过函数调用的方法来接受跨域接口响应回来的数据<scriptsrc="./js/yanshi.js?callback=name"></script>回调函数callback关键字找到想要调用的形参在jq中发起jsonp......
  • 解决git clone时报 Failed to connect to github.com 问题
    下图为我的解决方式:具体前置原因不可说!tttttzzzzz有开了vpn的小伙伴,注意下哦!另外,在解决过程中也有说,是dns的问题,上图解决不了的,可以去搜索下!!!......
  • Element-Plus的el-menu-item的index属性问题
    今天用Vue3+Element-Plus开发时,出现了以下问题Invalidprop:typecheckfailedforprop"index".ExpectedString|Null,gotNumberwithvalue8.、上网百度以及结合提示,可以得出结论: <el-menu-item></el-menu-item> 中的index属性,接受的值必须为字符串或null,而我在......
  • redis雪崩问题解决
    缓存雪崩出现的场景缓存服务器宕机,没有设置持久化介绍:缓存服务器宕机,没有设置持久化,导致缓存数据全部丢失,请求全部转发到数据库,造成数据库短时间内承受大量请求而崩掉。缓存集中失效缓存的key设置了相同的过期时间,导致在某一时刻,大量的key同时失效,请求全部转发到数据库,造成......