IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> AcWing 1020. 潜水员(二维费用01背包问题变形) -> 正文阅读

[数据结构与算法]AcWing 1020. 潜水员(二维费用01背包问题变形)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题目描述:

一共有 k 种 物品(气缸),对于第 i 种物品,第一维 费用(氧气体积) 是 v1i,第二维 费用(氮气体积) 是 v2i,价值(气缸重量) 是 wi
每个物品只能 被选一次

求一个 选择方案,使得第一维费用 至少为 n,第二维费用 至少为 m 且 总价值最小

思路:

闫氏dp分析法:
在这里插入图片描述

状态表示dp[i,j,k]:
集合:所有从i个物品中选,且氧气含量至少是j氮气含量至少是k的所有选法
属性:所有从
i个物品
中选,且氧气含量至少是j氮气含量至少是k的所有选法的气缸重量总和的最小值

状态计算
所有 不包含物品i 的所有选法:dp[i - 1, j, k]
所有 包含物品i 的所有选法:dp[i - 1, j - ai, k - bi]
因此,状态转移方程dp[j, k] = min(dp[j, k], dp[max(0, j - ai), max(0, k - bi)] + ci); (省去第一维)

细节处理:

(1)
初始化的细节处理:(对于要求体积 “至少是” 问题的初始化处理)
dp(0)(0)(0)=0:第一维为0(一件物品都不选),第二维和第三维体积均为0(氧气和氮气体积至少为0),
这种情况是合法的,且min值为0
dp(0)(1,2,3...)(1,2,3...):第一维为0(一件物品都不选),第二维和第三维体积至少为i(1,2,3…),
根据实际,这些状态都是不合法的(无法求min),因此将它们初始化为 即可(至于是+∞还是-∞取决于这个问题是求
最大值还是最小值)

(2)
即使所需要的氧气或者氮气所需的是数量是负数,但其所需数量与0是等价的,因此可以通过所需数量为0来转移,举个例子:体积至少为-2, 这种情况是存在的,体积是0,至少是-2,体积是10,至少也是-2
因此:j需要遍历到0k 需要遍历到 0

时间复杂度:

O ( n m k ) O(nmk) O(nmk)

代码:

#include<bits/stdc++.h>

using namespace std;

int n,m;
int k;
int ai,bi,ci;//第 i 个气缸里的氧和氮的容量及气缸重量
const int N = 22,M = 80;//氧,氮各自需要的量数据范围 
int dp[N][M];

int main()
{
	cin>>m>>n;
	cin>>k;
	//初始化 
	memset(dp,0x3f,sizeof dp);
//其它的所有方案(f[0][1,2,3...]),由于第一维为0(一件物品都不选),所以第二维体积必须为0不能为i(1,2,3...),
//这些状态都是不合法的,因此将它们初始化为∞即可
	dp[0][0]=0;
//第一维为0(一件物品都不选,代码中第一维),第二维体积为0此时只有f[0][0]是合法的
	
	for(int i=0;i<k;++i)
	{
		cin>>ai>>bi>>ci;
		for(int j=m;j>=0;--j)
		{
			for(int k=n;k>=0;--k)
			{
				dp[j][k]=min(dp[j][k],dp[max(0,j-ai)][max(0,k-bi)]+ci);
//这两维体积可以为负,此时置为0即可。举个例子:体积至少为-2,这种情况是存在的,体积是5,至少是-2,体积是10,
//至少也是-2
			}
		}
	}
	cout<<dp[m][n]<<endl;
//所有从前i个物品中选,且氧气含量至少是j, 氮气含量至少是k 的所有选法中 所需的气缸的重量总和的最低值
	return 0;
}

扩展:

求对于三类最大值最小值题型的初始化总结

  • 一、 体积最多是j(对应背包问题模板题)

    • dp数组全初始化为0
    • ①二维:f[i,k] = 00 <= i <= n, 0 <= k <= m(只会求价值的最大值)
    • ②一维:f[i] = 0, 0 <= i <= m(只会求价值的最大值)
    • 从实际含义进行推理,f[0,i]表示:一件物品都不选的情况下,体积最多为i时的最大价值,i不管取多少,什么都不选是一种方案,每个f[0,i]至少包含一个方案,f[0,i]的最大值为0
  • 二、 体积恰好是j

    • dp(0)=0dp(1,2,3...) = ∞,并保证V>=0
    • ①二维:
    • 当求价值的最小值f[0][0] = 0, 其余是inf
    • 当求价值的最大值f[0][0] = 0, 其余是-inf
    • ②一维:
    • 当求价值的最小值f[0] = 0, 其余是inf
    • 当求价值的最大值f[0] = 0, 其余是-inf
    • 此时,就只有f[0][0]是合法的,其它的所有方案(f[0][1,2,3...]),由于一件物品都不选,所以体积必须为0不能为i,这样的状态都是不合法的,因此将它们初始化为即可,至于是+∞还是-∞则取决于这个问题是求的最大值还是最小值。
  • 三、 体积至少为j

    • dp(0)=0dp(1,2,3...)=∞无需保证V>=0
    • ①二维:体积至少jf[0][0] = 0,其余是inf(只会求价值的最小值)
    • ②一维:体积至少jf[0] = 0,其余是inf(只会求价值的最小值)
    • 状态计算与第二种相同,只不过V可以为负,此时置为0即可。
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:47:47  更:2022-03-12 17:49:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:25:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码