0x07 内容简介与例题习题

0x07.基本算法 — 贪心 贪心 贪心是一种在每一次决策时都采用当前意义下最优策略的算法,因此,使用贪心算法要求问题的整体最优性可以由局部最优性导出。 贪心算法的正确性需要证明,常见的证明手段有: 微扰(邻项交换) 证明在任意局面下,任何对局部最优策略的微小改变都会造成整体结果变差,经常用于以排序为贪心策略的证明。 范围缩放 证明任何对局部最优策略作用范围的扩展都不会造成整体结果变差。 决策包容性 证明在任意局面下,做出局... 阅读详情

《算法竞赛进阶指南》读书笔记汇总
这里面是我在阅读《算法竞赛进阶指南》这本书时的一些思考,有兴趣可以瞧瞧!
如若发现什么问题,可以通过评论或者私信作者提出。希望各位大佬不吝赐教!

贪心的基本思想

贪心是一种在每次决策时采取当前意义下最优策略的算法。一般通过猜测得出策略之后,加以证明即可使用。通常的证明方法有以下几种:
反证法
邻项交换法(通过交换相邻两项,证明原决策比交换之后的决策更优)
决策包容性
范围扩展(证明任何对局部最优策略作用范围的扩展都不会造成整体结果变差)

那我们直接来看几道例题吧。

【例题】防晒(AcWing110)

题目链接
思路:
首先给出贪心策略:按照 m i n s p f minspf minspf递减的顺序把奶牛排序,依次考虑每只奶牛。对于每头奶牛,找到一瓶还有剩余的且 s p f spf spf值最大的防晒霜去用。
接下来我们来证明这个策略的正确性。这里使用范围扩展证明,考虑这一步策略的作用范围扩展到其他奶牛之后的影响。由于奶牛已经按照 m i n s p f minspf minspf值递减的顺序排序,所以每一瓶大于当前奶牛 m i n s p f minspf minspf值的防晒霜,都会大于之后奶牛的 m i n s p f minspf minspf值。那么也就是说, 对于当前奶牛可以使用的任意两瓶防晒霜而言,假设这两瓶防晒霜是 x , y x,y x,y,如果 s p f x < s p f y spf_{x}<spf_{y} spfx​<spfy​,那么对于之后的奶牛而言,对于这两瓶防晒霜,只有三种可能情况, x , y x,y x,y都能用、 x , y x,y x,y都不能用或者 x x x能用 y y y不能用。如果 x , y x,y x,y都不能用或者 x x x能用 y y y不能用,那么正确性显然。如果是 x , y x,y x,y都能用的情况,那么满足当前的奶牛与满足之后的奶牛是等价的,因为每只奶牛对答案的贡献是等价的,所以这个策略不会使得结果变差。

AC代码:

#include<bits/stdc++.h>
#define N 2505

using namespace std;

int n,m;
struct node{
    int mi,mx;
    bool operator < (const node& c)const{
        return mi > c.mi;
    }
}cow[N];

struct Node{
    int spf,cover;
    bool operator < (const Node& b) const{
        return spf > b.spf;
    }
}spfs[N];

void solve(){
    cin >> n >> m;
    for(int i = 1;i <= n;i ++)
        cin >> cow[i].mi >> cow[i].mx;
    for(int i = 1;i <= m;i ++)
        cin >> spfs[i].spf >> spfs[i].cover;

    sort(cow + 1,cow + 1 + n);
    sort(spfs + 1,spfs + 1 + m);

    int ans = 0;
    for(int i = 1;i <= n;i ++){
        for(int j = 1;j <= m;j ++){
            if(spfs[j].spf <= cow[i].mx && spfs[j].spf >= cow[i].mi && spfs[j].cover){
                ans ++;
                spfs[j].cover --;
                break;
            }
        }
    }

    cout << ans << endl;
}

int main(){
    solve();
    return 0;
}

【例题】国王游戏(AcWing114)

题目链接
思路:
首先给出贪心策略,按照每个大臣左、右手上数的乘积从小到大排序,就是最优排队方案。
接下来使用邻项交换法证明这个策略的正确性。
对于任意一种排队顺序,设 n n n名大臣左右手上的数字分别是 A [ 1 ] . . . A [ n ] A[1]...A[n] A[1]...A[n]与 B [ 1 ] . . . B [ n ] B[1]...B[n] B[1]...B[n],国王手里的数字是 A [ 0 ] A[0] A[0]与 B [ 0 ] B[0] B[0]
假设我们交换顺序的两位大臣是 i i i和 i + 1 i + 1 i+1,那么在交换之前这两位大臣获得的奖励分别为:
1 B [ i ] ∗ ∏ j = 0 i − 1 A [ j ] \frac{1}{B[i]}*\prod \limits_{j=0}^{i-1}A[j] B[i]1​∗j=0∏i−1​A[j]与 A [ i ] B [ i + 1 ] ∗ ∏ j = 0 i − 1 A [ j ] \frac{A[i]}{B[i + 1]}*\prod \limits_{j=0}^{i-1}A[j] B[i+1]A[i]​∗j=0∏i−1​A[j]
交换之后两位大臣获得的奖励为:
1 B [ i + 1 ] ∗ ∏ j = 0 i − 1 A [ j ] \frac{1}{B[i+1]}*\prod \limits_{j =0}^{i-1}A[j] B[i+1]1​∗j=0∏i−1​A[j]与 A [ i + 1 ] B [ i ] ∗ ∏ j = 0 i − 1 A [ j ] \frac{A[i+1]}{B[i]}*\prod \limits_{j=0}^{i-1}A[j] B[i]A[i+1]​∗j=0∏i−1​A[j]
我们要比较交换前后的最大值变换情况,其实就是比较下面两个式子:
m a x ( 1 B [ i ] , A [ i ] B [ i + 1 ] ) max(\frac{1}{B[i]}, \frac{A[i]}{B[i+1]}) max(B[i]1​,B[i+1]A[i]​)与 m a x ( 1 B [ i + 1 ] , A [ i + 1 ] B [ i ] ) max(\frac{1}{B[i +1]}, \frac{A[i+1]}{B[i]}) max(B[i+1]1​,B[i]A[i+1]​)
我们把他们同时乘上 B [ i ] ∗ B [ i + 1 ] B[i]*B[i+1] B[i]∗B[i+1]得到:
m a x ( B [ i + 1 ] , B [ i ] ∗ A [ i ] ) max(B[i+1], B[i]*A[i]) max(B[i+1],B[i]∗A[i])与 m a x ( B [ i ] , B [ i + 1 ] ∗ A [ i + 1 ] ) max(B[i], B[i+1]*A[i+1]) max(B[i],B[i+1]∗A[i+1])
由于所有的数都是正整数,那么 B [ i + 1 ] ≤ B [ i + 1 ] ∗ A [ i + 1 ] B[i+1] \le B[i+1]*A[i+1] B[i+1]≤B[i+1]∗A[i+1], B [ i ] ≤ B [ i ] ∗ A [ i ] B[i]\le B[i]*A[i] B[i]≤B[i]∗A[i]
所以只有当 A [ i ] ∗ B [ i ] ≤ A [ i + 1 ] ∗ B [ i + 1 ] A[i]*B[i]\le A[i+1]*B[i+1] A[i]∗B[i]≤A[i+1]∗B[i+1],交换前更优。也就是说,只要存在逆序对,那么交换逆序对可以使得情况变优。当无法交换也即按顺序时,为最优局面。得证。
使用这个贪心策略之后,用高精度写一下就好了。(高精好麻烦呜呜呜

AC代码:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

typedef pair<int, int> PII;

const int N = 1005, base = 10000;

PII nums[N];

void output(vector<int>& a)
{ 
    printf("%d", a.back());
    for (int i = a.size() - 2; i >= 0; i -- )
        printf("%04d", a[i]);
    puts("");
}

vector<int> mul(vector<int> a, int b)
{
    int t = 0;
    for (int i = 0; i < a.size(); i ++ )
    {
        a[i] = a[i] * b + t;
        t = a[i] / base;
        a[i] %= base;
    }
    while(t)
    {
        a.push_back(t % base);
        t /= base;
    }
        
    return a;
}

vector<int> div(vector<int> a, int b)
{
    int t = 0;
    for (int i = a.size() - 1; i >= 0; i -- )
    {
        a[i] += t * base;
        t = a[i] % b;
        a[i] /= b;
    }
    while(a.size() && a.back() == 0) a.pop_back();
    if (a.size() == 0) a.push_back(0);
    return a;
}

vector<int> max_vec(vector<int> a, vector<int> b)
{
    if (a.size() == b.size())
    {
        for (int i = a.size() - 1; i >= 0; i -- )
            if (a[i] > b[i]) return a;
            else if(b[i] > a[i]) return b;
        return a;
    }
    else if(a.size() > b.size()) return a;
    else return b;
}

int main()
{
    int n;
    scanf("%d", &n); 
    for (int i = 0; i <= n; i ++ )
    {
        int a, b;
        scanf("%d%d", &a, &b);
        nums[i] = {a * b, b};
    }
    sort(nums + 1, nums + 1 + n);
    
    vector<int> res(1, 1);
    vector<int> ans(1, 0);
    for (int i = 0; i <= n; i ++ )
    {
        if (i)
    	{
    		ans = max_vec(ans, div(res, nums[i].second));
		}
        res = mul(res, nums[i].first / nums[i].second);
	}
    
    output(ans);
    
    return 0;
}

未完成题目

【例题】给树染色(AcWing115)

【练习】任务(AcWing127)

【CRC简记式】x8 + x2 + x + 1的多项式为什么是07 下面是常用的CRC多项式表,其中这里的多项式一列又称简记式。可以发现比如第一个x4+ x + 1似乎应该表示为10011,即为0x13,这里为什么写0x03呢?这是因为生成多项式的最高幂次项系数是固定的1,故在简记式中,将最高的1统一去掉了! CRC算法名称 多项式公式 宽度 多项式 初始值 结果异或值 输入反转 输出反转 CRC-4/ITU x4+ x + 1 4 03 00 00 true true CRC.. 阅读详情

相关推荐

qualcomm MDM9X07 Debugmode

说明:该文档着重介绍Debug工具的设置方法。无线参数获取参见文档《debug_mode.odt》。 页面登录方法如下:下载软件路径://192.168.1.253/软件部/部门文档/平台性技术总结/AdminPWByIMEI_V1.1_20170110.rar,解压后打开软件,输入设备IMEI号,生成登录密码。登录密码生成算法参见文档《R700Dlink-Debug_mode功能介绍.docx

lihaifeng1234的博客 7702

单片机问题(关于index &= 0x07;无法理解 —— 数码管)

//数码管显示 void Nixie_Scan(void) { static unsigned char index = 0; //设置一个静态无符号字符型变量 index P2 = (P2 & 0x1f) | 0xe0; //数码管消隐 P0 =0xff; P2 = (P2 & 0x1f) | 0xc0; //数码管位选 P0 = 0x01 << index; //0000

纯粹,学术,热爱。 2307

准静态电磁场

叠加法 缺点:对于连续分布的电荷,叠加法的计算比较困难 虚位移法 概念 广义坐标:确实系统中导体形状、尺寸与位置的一组独立几何量。 广义力:企图改变某一广义坐标的力。 功:广义力乘上由它引起的广义坐标的改变量。 公式 ...

qq_35912930的博客 1860

一、C语言中的位运算符

执行0x11>>2的右移位运算,将二进制数向右移动2位(在低位补零),得到结果为0000 0100,转换为十六进制数为0x04。因此,0x11>>2的运算结果为0x04,其实际代表的二进制数为0000 0100。这个结果是通过将二进制数中每一位向右移两位来实现的,被移出的位被丢弃,空出的高位用0填充。若进行按位与运算,则只有当两个数的对应位都为1时,结果才为1,否则为0。把左边的运算数的各二进位全部左移若干位,由

weixin_51659166的博客 2116

openmediavault(OMV) (1)安装部署

EXT3(Third Extended File System): EXT3 是 Linux 中广泛使用的日志文件系统,是 EXT2 文件系统的升级版本。这里可以根据自己的需求进行设置,目前只设置了自动登出为1天,为方便后续配置使用,其他设置可根据自己的具体需求进行设置。通过cd 命令进入到我们的raid存储中,通过ls发现里面没有任何的数据,因为我们的raid存储中还未创建任何数据。我的系统要安装在100G的磁盘上,故选择100G的磁盘,实际可以根据具体情况选择。

Monster✺◟(∗❛ัᴗ❛ั∗)◞✺的博客 2168

【YOLOv8改进-损失函数】 YOLOv8自带损失函数CIoU / DIoU / GIoU 详解,以及如何切换损失函数

在介绍YOLOv8中的各种Iou之前,我们先来了解了解目标检测中的损失函数。目标检测模型通常包含两类损失函数:类别损失(分类)和位置损失(回归)。这两类损失函数用于检测模型的最后一部分,根据模型的输出(类别和位置)以及实际标注框(类别和位置),分别计算类别损失和位置损失。

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 5190

c语言阶段部分重点知识总结

这是一个特殊的内存区域,用于存储不可更改的数据,包括字符串常量。在这种情况下,指针指向的内存位置是只读的,也就是说不能直接修改字符串中的字符。需要注意的是,虽然指针指向的内存位置是只读的,但并不意味着整个指针都是只读的。如果您将一个字符串常量的地址赋给指针,您不能通过该指针来修改字符串的内容。通过使用结构体指针和指向结构体指针的方法,可以方便地操作结构体对象的成员变量,对其进行读取和修改。,而字符串指针指向的是字符串常量的地址。由于字符串常量是只读的,所以我们不能通过字符指针(*p)来修改字符串常量的值。

weixin_48241475的博客 282

我的世界进阶模组开发教程——制作机械动力附属模组

摘要: Create是Minecraft的机械动力模组,其代码结构分为多个关键模块: 数据生成系统:通过CreateRecipeProvider基类实现配方自动化生成,支持多步骤序列化装配配方(SequencedAssemblyRecipeGen),采用建造者模式链式调用; 注册管理:CreateRegistrate扩展了Registrate库,统一管理方块、流体、实体等注册,集成标签页分类和工具提示定制; 伤害系统:DamageTypeTagGen为机械伤害(如钻头、风扇火焰)定义原版兼容的标签; 客户端

qq_24992377的博客 2083

0x07 操作系统的线程知识

线程引入原因 性能 操作系统开销大; Unix的轻型进程(fork) 应用 进程代码并发执行的需求; 例子:PPT编辑(输入/拼写检查/存盘) 硬件 多核处理器; 加速进程的运行 线程 线程 可在CPU上运行的基本执行单位 进程内的一个代码片段可以被创建称为一个线程 线程状态:就绪、运行、等待等 线程操作:创建、撤销、等待、唤醒等 进程依旧是资源分配的基本单位 线程自己不拥有系统资源,通过进程申请资源 传统进程 重型进程 只有一个线程:主线程 单线程模型 进程和线程 方面 进

ChanCherry的博客 440

一文吃透 SAP HANA SDA:把分散数据当作本地数据来用的那把钥匙

摘要:SAP HANA SDA(Smart Data Access)技术详解:150字精要 SAP HANA SDA是一种数据虚拟化技术,允许在不复制数据的情况下访问远端数据源。核心功能包括: 通过Remote Source定义连接配置 创建Virtual Table作为本地代理 支持谓词下推优化查询性能 与SDI技术协同工作扩展数据集成能力 典型应用场景包括: 跨系统联邦查询 冷热数据分层管理 混合云数据整合 远程表复制(RTR)实现近实时数据同步 实施要点: 需关注适配器能力差异 合理运用查询下推优化

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 327

(2-2-2)位置控制算法:常用的位置控制算法(2)

例如下面是一个使用滑模控制算法实现机器人位置控制的例子,在该例子中,假设机器人在一维空间中移动,目标是使机器人的位置迅速、鲁棒地达到设定的目标位置。自适应控制算法通过实时地调整控制器参数,可以适应系统的变化,从而提高系统的鲁棒性和性能。模型预测控制(Model Predictive Control,MPC)是一种先进的控制策略,通常应用于动态系统,以实现对系统状态的优化控制。(6)迭代优化:随着时间推移,MPC迭代执行上述步骤,持续优化控制输入,以适应系统动态和外部扰动,实现对系统状态的稳健控制。

码农三叔 1608

OBD服务简述3-0x03/0x07/0x0A服务

OBD之0x03服务

qq_40633122的博客 1788

2026年复旦微电数字IC笔试试卷带答案解析

摘要: 本文为复旦微电子MCU/SOC岗位笔试模拟题,涵盖单片机架构、数字电路、存储技术等核心知识点。内容包括: 单选题(30分):考察Cortex-M中断机制、时序分析(建立/保持时间)、逻辑化简、跨时钟域设计(格雷码应用)、存储器特性(NAND Flash操作单元)等; 波形分析(15分):聚焦D触发器行为、时钟分频、建立时间违例判断及跨时钟域同步; 多选题(25分):涉及亚稳态成因与处理、异步FIFO设计要点、MCU低功耗策略、NAND Flash特性及复旦微电市场地位; 简答题(20分):解析建立/

Open 344

更新时出现错误代码0x800BFA0B或者0x800BFA07怎么办

目前有几个方法能供您尝试解决问题;方法一:1. 关闭Windows Update服务。——在搜索框或小娜中搜索“服务”或输入services.msc,回车,打开“服务”应用,找到“Windows Update”,右键选择“停止”。2. 删除更新文件。——删除路径 C:\Windows\SoftwareDistribution\DataStore和C:\Windows\SoftwareDistribution\Download下的所有文件。3. 重新开启Windows Update服务。

weixin_47908992的博客 1466

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

完美解决PC电脑0x0和0x800BFA07等错误,成功加入Windows10/11预览体验计划

很多人在加入Windows预览体验计划时,出现错误,无法加入,错误代码包括:0x0和0x800BFA07等等。尝试更换网络、修改DNS、修改注册表和重新注册Microsoft微软账号等方法,都无法解决,很是苦恼。究竟什么原因呢?通过检查,发现是注册表缺失或者错误导致的,这样就需要知道哪个注册表错误,并精准修改了。解决方法下载附件中的注册表,双击打开,运行,添加到系统的注册表中,然后再去重新尝试加入Windows预览体验计划,发现问题解决了,可以成功...

亚妮先森博客 9277

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

LeetCodeHot100_0x07

LeetCodeHot100_0x07 刷题情况总结 递归专题,受益甚多

wzc200406的博客 1199

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【嵌入式】HC32F07X ADC采样及软件滤波

单片机是数字芯片,只认识由0和1组成的逻辑序列。但实际情况下,生活中还有许多非0和1的模拟物理量存在,例如温度,湿度等。这时候往往需要使用到AD转换,AD转换的英文就是Analog(模拟) to Digital(数字) ,由模拟量转化为数字量;同理DA,则为Digital to Analog,数字量转化为模拟量。

sinat_33408502的博客 1460

mdm9x07的GPIO相关笔记

居然快一年没有更新博客了,近段时间看了下以前的一些笔记,发现做过的项目,学习的知识都忘了差不多,其实还是应该抽点时间出来记录下。 当然先列出参考文章: http://blog.chinaunix.net/uid-27717694-id-3624294.html                     GPIO的驱动模型 http://www.wowotech.net/gpio_subsyst

kinbo88的专栏 1万+

linux串口对0X0D、0X0A等特殊字符的处理

摘要:项目中使用STM32与RK3588串口通信传输温湿度数据时,出现CRC8校验失败问题。经排查发现,Linux端会将特殊字符(如0x0D、0x0A等)自动转换,导致接收数据被篡改,CRC校验值错误。解决方案是在Linux串口初始化时清除输入阶段的自动处理标志(IGNBRK、ICRNL等),使数据以原始形式接收。修改后,系统能正确接收特殊字符,CRC校验恢复正常。该问题表面偶现实为必现,关键在于禁用串口的自动转换功能。

沉在嵌入式的鱼的博客 1137

C++ Primer 0x07 练习题解

???? C++ Primer 0x07 练习题解 更好的阅读体验 7.1 定义抽象数据类型 7.1.1 定义抽象数据类型 7.1 使用2.6.1节定义的Sales_data类为 1.6节 的交易处理程序编写一个新版本。 #include <iostream> #include <string> struct Sales_data { std::string bookNo; unsigned units_sold = 0; double revenue = 0.0; }

鱼竿钓鱼干 513

Windows 0x80190001错误解决

解决Windows 0x80190001错误 本人系统版本为win10 2004 windows出现这样的错误,初步判断为windows的网络连接问题引起的,一般这个错误会导致用户账户无法登陆、windows商店无法显示内容、个人账户无法同步或验证等相关问题。下面我们来看看具体的修复方法。 修复 1、使用windows的搜索功能(或直接使用快捷键win+s),输入cmd,会出现命令行提示符,右键选择管理员身份运行;..................

Imagine Miracle的博客 18万+

解决方法:Linux串口接收字节0x11,0x0d,0x13丢失

一、背景 串口发送: read 44 byte: 5a a5 07 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 串口接收: read 43 byte: 5a a5 07 00 00 00 00 00...

Leung的博客 6692

安装Ubuntu14.04遇到filesystem type is ntfs,partition type 0x07问题的解决

根据网上教程在win7用EasyBCD安装Ubuntu14.04,配置EasyBCD文件具体如下 title Install Ubuntu 12.04 LTS    root (hd0,N)    kernel (hd0,N)/vmlinuz boot=casper iso-scan/filename=/ubuntu-14.04.1-desktop-amd64.iso ro

gladsnow的专栏 1万+
上一篇: 0x06 内容简介与例题习题
下一篇: 0x11 内容简介与例题习题
juruo_c
博客等级 码龄6年 520粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值