当前位置: 首页 > news >正文

算法【完全背包】

完全背包与01背包的区别仅在于每种商品可以选取无限次。时间复杂度O(物品数量 * 背包容量)

下面通过题目加深理解。

题目一

测试链接:疯狂的采药 - 洛谷

分析:这是一道完全背包的模板题。对于第i个物品的可能性展开也有两种,第一种是不取第i个物品,即就是从0到i-1个物品里面取剩余重量为j的最大价值;第二种是只取一个第i个物品,即从0到i个物品取剩余重量为j-一个i物品重量的最大值+一个i物品的价值。下面代码直接采用空间压缩的方法,对于此种相当标准的完全背包,应该记住其空间压缩的解法,对于一些带有完全背包性质的题,可以使用记忆化搜索,再改为严格位置依赖以及空间压缩等。因为题目有个测试答案超过int,所以为了通过dp用了指针,一般是直接定义dp为静态数组。代码如下。

#include <iostream>
using namespace std;
int t, m;
int herb[10001][2];
long long* dp; 
int main(void){scanf("%d%d", &t, &m);for(int i = 0;i < m;++i){scanf("%d%d", &herb[i][0], &herb[i][1]);}int length = (10000000 / m) + 2;dp = new long long [length];for(int i = 0;i < length;++i){dp[i] = 0;}for(int i = 0;i < m;++i){for(int j = 0;j <= t;++j){if(j - herb[i][0] >= 0){dp[j] = dp[j] > dp[j-herb[i][0]] + herb[i][1] ?dp[j] : dp[j-herb[i][0]] + herb[i][1];}}}printf("%ld", dp[t]);delete [] dp;return 0;
}

其中,dp数组表示在前i个物品里面取,剩余重量为j的情况下的最大价值。

题目二

测试链接:10. 正则表达式匹配 - 力扣(LeetCode)

分析:这道题需要注意可能性的展开。对于字符串s到了末尾而字符串p也到了末尾,则代表匹配成功;如果字符串s到了末尾且字符串p剩余的后缀能够成为一个空串也代表能够匹配成功;而字符串s没到末尾但字符串p到了末尾,代表匹配不成功。因为存在*的特殊情况,所以需要对下一位置是否为*分情况讨论。下一个位置不是*时,如果当前两个字符串的字符能够匹配成功,则整个字符串是否匹配成功取决于后一位置的字符匹配;如果匹配不成功,则不论后一位置匹配能否成功,都是不成功的。如果下一位置为*则具有完全背包性质,可以不取即直接跳过当前位置和当前位置之后的*,从*之后的位置开始匹配;或者如果当前位置能够匹配成功,则可多次使用当前位置与下一位置的*进行匹配。下面代码为记忆化搜索版本。代码如下。

class Solution {
public:int dp[20][20];int f(int index1, int index2, string s, string p){if(index1 == s.size()){if(index2 == p.size()){return 1;}else{return index2 + 1 < p.size() && p[index2+1] == '*' && f(index1, index2+2, s, p);}}if(index2 == p.size()){return 0;}if(dp[index1][index2] != -1){return dp[index1][index2];}char ch1 = s[index1];char ch2 = p[index2];int ans;if((index2+1 < p.size() && p[index2+1] != '*') || index2+1 == p.size()){if(ch1 != ch2 && ch2 != '.'){ans = 0;}else{ans = f(index1+1, index2+1, s, p);}}else{ans = f(index1, index2+2, s, p);if(ch1 == ch2 || ch2 == '.'){ans |= f(index1+1, index2, s, p);}}dp[index1][index2] = ans;return ans;}void build(){for(int i = 0;i < 20;++i){for(int j = 0;j < 20;++j){dp[i][j] = -1;}}}bool isMatch(string s, string p) {build();return f(0, 0, s, p);}
};

其中,f方法表示在以字符串s的index1下标开始,字符串p的index2的下标开始匹配的情况下,返回能否匹配成功。这里不用bool类型是因为,dp需要1表示成功,0表示失败,-1表示未赋值。

题目三

测试链接:44. 通配符匹配 - 力扣(LeetCode)

分析:这道题和上一道题类似,不过可能性少了许多。对于字符是否是*分情况讨论,如果不是*且当前字符能够匹配成功,则整个字符串能否匹配成功取决于后一位置的字符匹配;如果当前位置为*,则可以不要这个*,即从下一位置开始匹配或者重复使用多次这个*即匹配一个字符序列。需要注意的是下面的代码分别是记忆化搜索、严格位置依赖、空间压缩的版本,并且记忆化搜索会超时。代码如下。

class Solution {
public:int dp[2000][2000];void build(){for(int i = 0;i < 2000;++i){for(int j = 0;j < 2000;++j){dp[i][j] = -1;}}}int f(int index1, int index2, string s, string p){if(index1 == s.size()){if(index2 == p.size()){return 1;}else{return p[index2] == '*' && f(index1, index2+1, s, p);}}if(index2 == p.size()){return 0;}if(dp[index1][index2] != -1){return dp[index1][index2];}char ch1 = s[index1];char ch2 = p[index2];int ans;if(ch2 != '*'){ans = (ch1 == ch2 || ch2 == '?') && f(index1+1, index2+1, s, p);}else{ans = f(index1, index2+1, s, p);ans |= f(index1+1, index2, s, p);}dp[index1][index2] = ans;return ans;}bool isMatch(string s, string p) {build();return f(0, 0, s, p);}
};

其中,f方法表示在以字符串s的index1下标开始,字符串p的index2的下标开始匹配的情况下,返回能否匹配成功。

class Solution {
public:bool dp[2001][2001];bool isMatch(string s, string p) {int length1 = s.size();int length2 = p.size();dp[length1][length2] = true;for(int index2 = length2-1;index2 >= 0;--index2){dp[length1][index2] = p[index2] == '*' && dp[length1][index2+1];}for(int index1 = length1-1;index1 >= 0;--index1){dp[index1][length2] = false;}for(int i = length1-1;i >= 0;--i){for(int j = length2-1;j >= 0;--j){if(p[j] != '*'){dp[i][j] = (s[i] == p[j] || p[j] == '?') && dp[i+1][j+1];}else{dp[i][j] = dp[i][j+1] || dp[i+1][j];}}}return dp[0][0];}
};

其中,dp数组的初始化参考记忆化搜索时递归的出口条件;dp数组的含义和记忆化搜索的f方法含义一样。

class Solution {
public:bool dp[2001];bool isMatch(string s, string p) {int length1 = s.size();int length2 = p.size();bool temp1, temp2;dp[length2] = true;for(int index2 = length2-1;index2 >= 0;--index2){dp[index2] = p[index2] == '*' && dp[index2+1];}for(int i = length1-1;i >= 0;--i){temp1 = i == length1-1 ? true : false;dp[length2] = false;for(int j = length2-1;j >= 0;--j){temp2 = dp[j];if(p[j] != '*'){dp[j] = (s[i] == p[j] || p[j] == '?') && temp1;}else{dp[j] = dp[j+1] || dp[j];}temp1 = temp2;}}return dp[0];}
};

对于这道题的空间压缩需要使用到辅助变量存储一些值。

题目四

测试链接:[USACO08NOV] Buying Hay S - 洛谷

分析:对于这道题,主要思路是使用二分答案法得到每次的开销,对于得到的开销求出采购到的最大甘草磅数能否满足题目条件,根据能否满足条件进行二分,继续求得开销(二分答案法详情见拙作 算法【二分答案法】)。代码如下。

#include <iostream>
#include <vector>
using namespace std;
int N, H;
int firm[100][2];
vector<int> dp;
bool f(int cost){dp.assign(cost+1, 0);for(int i = 0;i < N;++i){for(int j = 0;j <= cost;++j){if(j - firm[i][1] >= 0){dp[j] = dp[j] > dp[j-firm[i][1]] + firm[i][0] ?dp[j] : dp[j-firm[i][1]] + firm[i][0];}}}return dp[cost] >= H;
}
int main(void){int max_cost = 0;int ans;scanf("%d%d", &N, &H);for(int i = 0;i < N;++i){scanf("%d%d", &firm[i][0], &firm[i][1]);max_cost = max_cost > ((H + firm[i][0] - 1)/firm[i][0]) * firm[i][1] ?max_cost : ((H + firm[i][0] - 1)/firm[i][0]) * firm[i][1];}int left = 0, right = max_cost, middle;while (left <= right){middle = left + (right - left) / 2;if(f(middle)){ans = middle;right = middle - 1;}else{left = middle + 1;}}printf("%d", ans);return 0;
}

相关文章:

算法【完全背包】

完全背包与01背包的区别仅在于每种商品可以选取无限次。时间复杂度O(物品数量 * 背包容量) 下面通过题目加深理解。 题目一 测试链接&#xff1a;疯狂的采药 - 洛谷 分析&#xff1a;这是一道完全背包的模板题。对于第i个物品的可能性展开也有两种&#xff0c;第一种是不取第…...

二叉树的遍历

有一个结点的二叉树。给出每个结点的两个子结点编号&#xff0c;建立一棵二叉树&#xff0c;如果是叶子结点&#xff0c;则输入 0 0。 建好树这棵二叉树之后&#xff0c;依次求出它的前序、中序、后序列遍历。 输入格式: 第一行一个整数n &#xff0c;表示结点数。 之后n 行…...

1.31 实现五个线程的同步

1.使用互斥锁实现 1>程序代码 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include &l…...

three.js+WebGL踩坑经验合集(6.1):负缩放,负定矩阵和行列式的关系(2D版本)

春节忙完一轮&#xff0c;总算可以继续来写博客了。希望在春节假期结束之前能多更新几篇。 这一篇会偏理论多一点。笔者本没打算在这一系列里面重点讲理论&#xff0c;所以像相机矩阵推导这种网上已经很多优质文章的内容&#xff0c;笔者就一笔带过。 然而关于负缩放&#xf…...

【开源免费】基于SpringBoot+Vue.JS体育馆管理系统(JAVA毕业设计)

本文项目编号 T 165 &#xff0c;文末自助获取源码 \color{red}{T165&#xff0c;文末自助获取源码} T165&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

《大数据时代“快刀”:Flink实时数据处理框架优势全解析》

在数字化浪潮中&#xff0c;数据呈爆发式增长&#xff0c;实时数据处理的重要性愈发凸显。从金融交易的实时风险监控&#xff0c;到电商平台的用户行为分析&#xff0c;各行业都急需能快速处理海量数据的工具。Flink作为一款开源的分布式流处理框架&#xff0c;在这一领域崭露头…...

antdesignvue统计数据源条数、计算某列合计值、小数计算不精确多了很多小数位

1.在</a-table>下方加如下代码 <div>数据总条数&#xff1a;{ {tableData.length}}&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp <template>A列合计&#xff1a;{ {sum}}</template> </div> 注&#xff1a;tableData为<a-tabl…...

02.05、链表求和

02.05、[中等] 链表求和 1、题目描述 给定两个用链表表示的整数&#xff0c;每个节点包含一个数位。 这些数位是反向存放的&#xff0c;也就是个位排在链表首部。 编写函数对这两个整数求和&#xff0c;并用链表形式返回结果。 2、解题思路 本题要求对两个链表表示的整数…...

dmfldr实战

dmfldr实战 本文使用达梦的快速装载工具&#xff0c;对测试表进行数据导入导出。 新建测试表 create table “BENCHMARK”.“TEST_FLDR” ( “uid” INTEGER identity(1, 1) not null , “name” VARCHAR(24), “begin_date” TIMESTAMP(0), “amount” DECIMAL(6, 2), prim…...

Kafka 副本机制(包含AR、ISR、OSR、HW 和 LEO 介绍)

文章目录 Kafka 副本机制&#xff08;包含AR、ISR、OSR、HW 和 LEO 介绍&#xff09;1. 副本的基本概念2. 副本同步和一致性2.1 AR&#xff08;Assigned Replicas&#xff09;2.2 ISR&#xff08;In-Sync Replicas&#xff09;2.3 OSR&#xff08;Out-of-Sync Replicas&#xf…...

爬虫基础(二)Web网页的基本原理

一、网页的组成 网页由三部分构成&#xff1a;HTML、JavaScript、CSS。 &#xff08;1&#xff09;HTML HTML 相当于网页的骨架&#xff0c;它通过使用标签来定义网页内容的结构。 举个例子&#xff1a; 它把图片标签为img、把视频标签为video&#xff0c;然后组合到一个界面…...

外网访问禅道软件项目管理系统

禅道项目管理软件是一款国产的开源免费项目管理软件&#xff0c;专注于研发项目管理&#xff0c;旨在帮助企业或团队提高项目管理的效率和质量。 本文将详细的介绍如何在 Windows 系统电脑端下载运行禅道软件项目管理系统&#xff0c;并且结合路由侠内网穿透实现外网访问本地的…...

Python 梯度下降法(五):Adam Optimize

文章目录 Python 梯度下降法&#xff08;五&#xff09;&#xff1a;Adam Optimize一、数学原理1.1 介绍1.2 符号说明1.3 实现流程 二、代码实现2.1 函数代码2.2 总代码2.3 遇到的问题2.4 算法优化 三、优缺点3.1 优点3.2 缺点 四、相关链接 Python 梯度下降法&#xff08;五&a…...

笔试-二进制

应用题 将符合区间[l,r]内的十进制整数转换为二进制表示&#xff0c;请问不包含“101”的整数个数是多少&#xff1f; 实现 l int(input("请输入下限l&#xff0c;其值大于等于1&#xff1a;")) r int(input("请输入上限r&#xff0c;其值大于等于l&#x…...

springboot 2.7.6 security mysql redis jwt配置例子

数据库结构用的是若依的数据库基本结构,ruoyi.vip。 总体参考了文章&#xff1a;https://blog.csdn.net/qq_45847507/article/details/126681110 本文章只包含不同的地方&#xff0c;相同的不再赘述。 1、创建spring工程&#xff0c;jdk1.8&#xff0c;maven。 pom.xml中依赖部…...

FreeRTOS从入门到精通 第十六章(任务通知)

参考教程&#xff1a;【正点原子】手把手教你学FreeRTOS实时系统_哔哩哔哩_bilibili 一、任务通知简介 1、概述 &#xff08;1&#xff09;任务通知顾名思义是用来通知任务的&#xff0c;任务控制块中的结构体成员变量ulNotifiedValue就是这个通知值。 &#xff08;2&#…...

TensorFlow 简单的二分类神经网络的训练和应用流程

展示了一个简单的二分类神经网络的训练和应用流程。主要步骤包括&#xff1a; 1. 数据准备与预处理 2. 构建模型 3. 编译模型 4. 训练模型 5. 评估模型 6. 模型应用与部署 加载和应用已训练的模型 1. 数据准备与预处理 在本例中&#xff0c;数据准备是通过两个 Numpy 数…...

无人机图传模块 wfb-ng openipc-fpv,4G

openipc 的定位是为各种模块提供底层的驱动和linux最小系统&#xff0c;openipc 是采用buildroot系统编译而成&#xff0c;因此二次开发能力有点麻烦。为啥openipc 会用于无人机图传呢&#xff1f;因为openipc可以将现有的网络摄像头ip-camera模块直接利用起来&#xff0c;从而…...

.cc扩展名是什么语言?C语言必须用.c为扩展名吗?主流编程语言扩展名?Java为什么不能用全数字的文件名?

.cc扩展名是什么语言? .cc是C语言使用的扩展名&#xff0c;一种说法是它是c with class的简写&#xff0c;当然C语言使用的扩展名不止.cc和.cpp, 还包含.cxx, .c, .C等&#xff0c;这些在不同编译器系统采用的默认设定不同&#xff0c;需要区分使用。当然&#xff0c;编译器提…...

【MyDB】4-VersionManager 之 3-死锁及超时检测

【MyDB】4-VersionManager 之 3-死锁及超时检测 死锁及超时检测案例背景LockTable锁请求与等待管理 addvm调用addputIntoList&#xff0c;isInList&#xff0c;removeFromList 死锁检测 hasDeadLock方法资源释放与重分配 参考资料 死锁及超时检测 本章涉及代码&#xff1a;top/…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...

(12)-Fiddler抓包-Fiddler设置IOS手机抓包

1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求&#xff0c;也可以截获各种智能手机发出的HTTP/ HTTPS 请求。 Fiddler 能捕获Android 和 Windows Phone 等设备发出的 HTTP/HTTPS 请求。同理也可以截获iOS设备发出的请求&#xff0c;比如 iPhone、iPad 和 MacBook 等苹…...