反悔贪心和例题

反悔贪心

什么是反悔贪心:

  • 我们都知道贪心就是把局部最优解作为整体最优解,然后一步步的迭代,直到找到全局最优解的过程。但是有些时候,贪心策略可能并不是正解,局部的最优解可能不是全局的最优解。
  • 反悔贪心顾名思义就是带反悔的贪心。我们先找到局部的最优解,如果枚举到后面,发现之前选取的不是最优解,那么我们要做一个反悔操作,修改之前的局部最优解。但这个修改并不是真的改掉之前的操作,而是在之前局部最优解的基础上进行修改,达到反悔的效果
例题1:CF865D

您可以完美预测某只股票未来 N N N 天的价格。每天你要么买入一股,要么卖出一股,要么什么都不做。起初你拥有零股,当你没有任何股票时,你不能卖出股票。在 N N N 天结束时,您希望再次拥有零股,但希望拥有尽可能多的资金。

  • 正解一定是买便宜的再买贵的,遍历所有股票,如果在这张股票之前有比它便宜的,肯定是在便宜的一天买,在贵的一天卖。可以用小根堆维护前面最便宜的数字。
  • 但是有一组数据 1,2,100可以卡掉这个贪心,如果在第二天发现第一天便宜,就在第一天买,第二天卖,那么第三天就没有股票卖了。策略显然是先买 1 1 1,后卖 100 100 100
  • 这时贪心不是局部最优解,我们考虑可不可以进行反悔操作。首先在第二天时, s u m + = a [ 2 ] − a [ 1 ] sum+=a[2]-a[1] sum+=a[2]a[1],在遍历的过程中发现 100 100 100 显然更优。那么这时如果要反悔,不卖掉 a [ 2 ] a[2] a[2],去卖掉 a [ 3 ] a[3] a[3]。有 s u m + = a [ 3 ] − a [ 2 ] sum+=a[3]-a[2] sum+=a[3]a[2]。这个过程,跟买了 a [ 2 ] a[2] a[2],卖掉 a [ 3 ] a[3] a[3] 的过程很相似,唯一的区别就是在这之前已经有了一步 s u m + = a [ 2 ] − a [ 1 ] sum+=a[2]-a[1] sum+=a[2]a[1]。这时如果物品 a [ 3 ] a[3] a[3] 选取了 a [ 2 ] a[2] a[2] ,就达到了 s u m = a [ 3 ] − a [ 1 ] sum=a[3]-a[1] sum=a[3]a[1] 的效果。
  • 大概流程就是,如果某一天 a [ j ] a[j] a[j] 发现前面一天比它便宜,就在小根堆里面把 a [ i ] a[i] a[i] 弹出,更新 s u m sum sum 的值。弹出的物品就是买的股票,然后放入两次 a [ j ] a[j] a[j],第一次代表正常贪心购买 a [ j ] a[j] a[j]。第二次代表反悔操作,把 a [ i ] a[i] a[i] 卖掉,然后重新放回 a [ j ] a[j] a[j]
  • 每次反悔操作不会导致某一天进行了买入又卖出的操作,因为如果反悔,卖出的一定是当前这一天。
  • 代码如下:
    // LUOGU_RID: 166565189
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    #define inf 0x3f3f3f3f3f3f3f3f
    const int N=1e6+10;
    const int mod=1e9+7;
    int a[N];
    signed main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n;cin>>n;priority_queue<int,vector<int>,greater<int>> q;int sum=0;for(int i=1;i<=n;i++){int x;cin>>x;if(q.empty()||q.top()>=x){q.push(x);}else{sum+=x-q.top();q.pop();q.push(x);q.push(x);}}cout<<sum<<endl;return 0;
    }
    
例题2:Luogu P1484 种树

cyrcyr 今天在种树,他在一条直线上挖了 n n n 个坑。这 n n n 个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr 不会在相邻的两个坑中种树。而且由于 cyrcyr 的树种不够,他至多会种 k k k 棵树。假设 cyrcyr 有某种神能力,能预知自己在某个坑种树的获利会是多少(可能为负),请你帮助他计算出他的最大获利。

  • 题意简单来说,是给定 n n n 个数,选取不能两两相邻的 k k k 个数,求最大和。
  • 我们先不考虑 k k k 个数字的限制,如果都是正数,那么我们选取的串一定是01010101010101两种情况。
  • 再考虑 k k k 很小的情况,我们发现,如果 k = 1 k=1 k=1,选取的一定是价值最大的坑,如果 k = 2 k=2 k=2 ,设最大数为 x x x, 选取的要么是 x x x 和扣掉 x x x 相邻两个数剩下区间的最大数,要么就是选取 x x x 相邻两个数,不会出现只选取相邻一个数的情况,因为这样选取 x x x, 一定比选相邻数更优。
  • 加上 k k k 的限制之后,我们选取的 01 01 01 串应该变成什么样呢?它一定是某些 01 01 01 交替串和一些 0 0 0 的连接
  • 考虑反悔贪心,如果选取串 1 1 1 ,向后遍历,如果 101 101 101 1 1 1 更优,就应该把101换成1,同理,如果 10101 10101 10101 101 101 101 更优,也要把它放进去。推一遍式子:
  • v [ 1 ] = a [ 3 ] , v [ 101 ] = a [ 2 ] + a [ 4 ] , v [ 10101 ] = a [ 1 ] + a [ 3 ] + a [ 5 ] v[1]=a[3],v[101]=a[2]+a[4],v[10101]=a[1]+a[3]+a[5] v[1]=a[3],v[101]=a[2]+a[4],v[10101]=a[1]+a[3]+a[5]
  • v [ 101 ] = v [ 1 ] + a [ 2 ] + a [ 4 ] − a [ 3 ] , v [ 10101 ] = v [ 101 ] + a [ 1 ] + a [ 5 ] − ( a [ 2 ] + a [ 4 ] − a [ 3 ] ) v[101]=v[1]+a[2]+a[4]-a[3],v[10101]=v[101]+a[1]+a[5]-(a[2]+a[4]-a[3]) v[101]=v[1]+a[2]+a[4]a[3],v[10101]=v[101]+a[1]+a[5](a[2]+a[4]a[3])
  • 可以发现,如果将 $ f_子=a[l]+a[r]-v[子串] $ 放入,那么$ v[父串]=v[子串]+f_子 $ 所以每次只需要把 $f_子 放入,就可以反悔。
  • 用双向链表维护 l l l r r r,由于每次反悔只增加一个,跟选取元素差不多。跟例题1类似。大根堆维护就行了
  • 代码如下:
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    #define inf 0x3f3f3f3f3f3f3f3f
    #define pii pair<int, int>
    #define endl '\n'
    const int N=3e5+10;
    const int mod=1e9+7;
    int a[N],vis[N];
    map<int, int> l,r;
    priority_queue<pii> q;
    signed main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n,k;cin>>n>>k;for(int i=1;i<=n;i++){cin>>a[i];l[i]=i-1;r[i]=i+1;q.push(make_pair(a[i],i));}int sum=0;for(int i=1;i<=k;i++){while(!q.empty()&&vis[q.top().second]) q.pop();pii now=q.top();q.pop();if(now.first<=0) break;sum+=now.first;vis[l[now.second]]=vis[r[now.second]]=1;now.first=a[now.second]=a[l[now.second]]+a[r[now.second]]-now.first;q.push(now);l[now.second]=l[l[now.second]];r[now.second]=r[r[now.second]];r[l[now.second]]=l[r[now.second]]=now.second;}cout<<sum<<endl;return 0;
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/47425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SSM架构(二)

接上一篇博客 SSM框架(一)-CSDN博客 2.4 Spring 2.4.1 Service设计 EmployeeService接口代码&#xff1a; List<Emp> search(Emp condition);Emp searchById(Integer id);boolean add(Emp emp);boolean update(Emp emp);boolean delete(Integer id); EmployeeServic…

聊聊不再兼容安卓的鸿蒙

鸿蒙NExt已经确定不再兼容安卓系统&#xff0c;这意味着鸿蒙系统在更新迭代上将会展现出更加迅猛的速度。不过&#xff0c;这样的变化也给开发者们带来了不小的挑战。如今&#xff0c;鸿蒙的开发主要推荐使用的是ArkTS&#xff0c;而不是我们熟悉的Java SDK。对于大量习惯于使用…

【C++刷题】[UVA 489]Hangman Judge 刽子手游戏

题目描述 题目解析 这一题看似简单其实有很多坑&#xff0c;我也被卡了好久才ac。首先题目的意思是&#xff0c;输入回合数&#xff0c;一个答案单词&#xff0c;和一个猜测单词&#xff0c;如果猜测的单词里存在答案单词里的所有字母则判定为赢&#xff0c;如果有一个字母是答…

Unity3d开发google chrome的dinosaur游戏

游戏效果 游戏中&#xff1a; 游戏中止&#xff1a; 一、制作参考 如何制作游戏&#xff1f;【15分钟】教会你制作Unity小恐龙游戏&#xff01;新手15分钟内马上学会&#xff01;_ unity教学 _ 制作游戏 _ 游戏开发_哔哩哔哩_bilibili 二、图片资源 https://download.csdn.…

9.Kafka消费者API实践

目录 概述实践topic消费者效果 消费指定topic的某个分区代码效果kafka分区策略-Range 概述 Kafka消费者API实践 实践 topic # ./kafka-topics.sh --bootstrap-server localhost:9092 --create --partitions 3 --replication-factor 1 --topic test03 [roothadoop02 bin]# ./…

【问题解决】Jetson nano 安装pytorch使用GPU推理

一. 问题描述 安装 yolov8 后只调用cpu推理图片 二. 解决步骤 2.1 在推理环境下&#xff0c;执行下面命令卸载pytorch pip uninstall torch torchtext torchaudio2.2 下载PyTorch的依赖: sudo apt-get -y update; sudo apt-get -y install libopenblas-dev;###2.3 下载py…

深入全面概括C语言的运算符

目录 二.算术运算符 三.自增自减运算符 四.赋值运算符 五.关系运算符 六.逻辑运算符 七.三元运算符 九.运算符的优先级 一.前言 c语言的运算符可以分为六种&#xff0c;分别是&#xff1a;1.算术运算符&#xff1b;2.自增自减运算符&#xff1b;3.赋值运算符&#xff1b…

uniapp转小程序,小程序转uniapp方法

&#x1f935; 作者&#xff1a;coderYYY &#x1f9d1; 个人简介&#xff1a;前端程序媛&#xff0c;目前主攻web前端&#xff0c;后端辅助&#xff0c;其他技术知识也会偶尔分享&#x1f340;欢迎和我一起交流&#xff01;&#x1f680;&#xff08;评论和私信一般会回&#…

python-字符金字塔(赛氪OJ)

[题目描述] 请打印输出一个字符金字塔&#xff0c;字符金字塔的特征请参考样例。输入格式&#xff1a; 输入一个字母&#xff0c;保证是大写。输出格式&#xff1a; 输出一个字母金字塔&#xff0c;输出样式见样例。样例输入 C样例输出 A ABA …

【ffmpeg命令基础】过滤处理

文章目录 前言过滤处理的介绍两种过滤类型简单滤波图简单滤波图是什么简单滤波示例 复杂滤波图复杂滤波是什么区别示例 总结 前言 FFmpeg是一款功能强大的开源音视频处理工具&#xff0c;广泛应用于音视频的采集、编解码、转码、流化、过滤和播放等领域。1本文将重点介绍FFmpe…

Docker入门:从安装到实际应用

Docker入门指南&#xff1a;从安装到实际应用 Docker 是一个开源的平台&#xff0c;允许开发者通过容器技术来部署、管理和运行应用程序。容器是一种轻量级、独立的运行环境&#xff0c;可以包含应用程序及其所有依赖项&#xff0c;从而确保在不同环境下运行一致。本文将介绍 …

Python、Rust与AI的未来展望

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

【关于PHP性能优化,内存优化,日志工具等问题处理】

目录 PHP 性能优化&#xff1a; 如何优化 PHP 代码以提高性能&#xff1f; 通用优化策略&#xff1a; 框架特定优化&#xff1a; 性能优化最佳实践&#xff1a; 描述一下你使用过的 PHP 性能分析工具。 检测内存泄漏的方法 使用工具检测内存泄漏 常见内存泄漏场景及解决…

FastAdmin: 一款基于ThinkPHP+Bootstrap的极速后台开发框架(Gitee最有价值开源项目)

欢迎加入我们前端技术学习交流群&#xff0c;关注“前端组件开发”公众号&#xff0c;私信可申请入群 摘要&#xff1a; 随着Web技术的快速发展&#xff0c;后台管理系统的开发效率与灵活性成为了项目成功的关键。FastAdmin作为一款基于ThinkPHP和Bootstrap的开源后台框架&…

基于 Vue 3 和 Element Plus 构建图书管理系统

基于 Vue 3 和 Element Plus 构建图书管理系统 本文将介绍如何使用 Vue 3 和 Element Plus 构建一个简单的图书管理系统。这个系统将包括以下功能&#xff1a; 添加新书显示图书列表分页显示图书删除图书 相关链接 接口地址 elementplus中文地址 项目结构 我们的项目结构…

Langchain[4]:Langchain 0.2革命性突破:结合工具调用与结构化数据处理、@Chain修饰符使用,解决LLM输出难题,提升AI效能

Langchain[4]:Langchain 0.2革命性突破:结合工具调用与结构化数据处理,解决LLM输出难题,提升AI效能 1.工具调用 大型语言模型 (LLM) 可以通过工具调用功能与外部数据源交互。工具调用是一种强大的技术,允许开发人员构建复杂的应用程序,这些应用程序可以利用 LLM 访问、交…

websocket-react使用

问题 在一个应用中&#xff0c;如果需要在不同的组件之间共享同一个WebSocket连接&#xff0c;可以采用多种方法来实现。 比如&#xff1a;单例模式、全局变量、react context React上下文&#xff08;React Context&#xff09; 如果你使用的是React&#xff0c;可以使用Re…

C++ | Leetcode C++题解之第239题滑动窗口最大值

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {int n nums.size();vector<int> prefixMax(n), suffixMax(n);for (int i 0; i < n; i) {if (i % k 0) {prefixMax[i] num…

Writing Bazel rules: data and runfiles

Bazel has a neat feature that can simplify a lot of work with tests and executables: the ability to make data files available at run-time using data attributes. You may have seen these in rules like this:Bazel 有一个巧妙的功能&#xff0c;可以简化测试和可执…

简单实用的企业舆情安全解决方案

前言&#xff1a;企业舆情安全重要吗&#xff1f;其实很重要&#xff0c;尤其面对负面新闻&#xff0c;主动处理和应对&#xff0c;可以掌握主动权&#xff0c;避免股价下跌等&#xff0c;那么如何做使用简单实用的企业舆情解决方案呢&#xff1f; 背景 好了&#xff0c;提取词…