CF1380D.Berserk And Fireball 【2000】你值得学习的【思维】+【模拟】+【贪心】
链接
CF1380D.Berserk And Fireball
题意
- 存在 nnn 个战士
- 两种技能
- 第一种,消费 xxx 点魔力值,消灭连续的 kkk 个战士
- 第二种,消费 yyy 点魔力值,选择两个连续战士,战斗力大的消灭战斗力小的
- 经过消费魔力的多次两种操作,使得 aaa 数组变成 bbb 数组,问最少需要花费的魔力值是多少?
- 若无法使 aaa 数组变成 bbb 数组,则输出 −1-1−1
- 两种操作图示方框颜色是不相同的,希望能够有好的阅读体验。
样例输入
5 2
5 2 3
3 1 4 5 2
3 5
样例输出
8
解释
- 原数组
- 1、4 两元素恰好长度为2,于是我们进行1操作,花费x(5)魔力值消灭连续的k(2)个战士
- 5、2两元素的小值恰好是我们需要删除的2,且单一2元素的长度为1不合适进行操作1,所以选择操作2进行,花费魔力值3
- 最后所花费的魔力值为 8 = 5 + 3
以上图示符合样例1的输出情况
无解情况
样例输入
4 4
5 1 4
4 3 1 2
2 4 3 1
样例输出
-1
很明显相同长度的两个数组,元素的相对位置完全不同已经不能通过操作1、2进行改变了,因为操作1、2都没有改变元素的相对位置。
疑问1
为什么不进行操作2?(那好,我们来尝试下操作2消灭【1,4】的情况)
结果:
总花费:6魔力值>5魔力值(操作1)
归纳:这么说来操作2也不是不行,主要取决于我操作1和操作2的魔力值单次消耗情况和能否进行删除(因为在这样例中是恰好3>13>13>1且4<54<54<5,刚好小的都是需要删除的)
想法:因此我们需要根据各种操作的魔力值消费情况进行贪心。
题解
- 我们将该数组序列进行一下划分,划分为多个区间,这是为了根据不同区间的长度考虑进行操作1还是操作2,参考上面的疑问1。
- 我们设区间长度为 LLL
- 当L<kL< kL<k时,区间最大值大于左右端点,则无解,这是因为大值是你想要消灭的,你却没有办法通过操作2进行消灭,如果区间最大值不大于左右端点, 魔法消耗就是 L * y,(两个值消灭一个值,需要消灭长度为L,即L * y,这里不太理解可以看一下单调队列)
- 当L>=kL>=kL>=k时,区间最大值大于左右端点,那么我们可以进行操作2花费x的魔力值,消灭长度为k的战士。
注意:程序中途中的乘积会爆int
代码
/*
* n个战士
* 两种技能 1.x 魔力值 ,连续消灭k个战士 2.y魔力值,选择两个连续战士,战斗力大的消灭战斗力小的
* ai -> bi
*/
const int maxn = 2e5 + 50;
int a[maxn], b[maxn];
LL x, k, y;
int n, m;
bool solve(int l, int r, LL &ans){bool judge = false; //当L< k时,区间最大值大于左右端点,则无解;if (l > r) return true;//我们区间的有解和无解是通过判断区间中最大值的情况来解决的,因此我们需要寻找最大值int maxIndex = l;int L = r - l + 1; //区间长度FOR_1(i, l, r) if (a[i] > a[maxIndex]) maxIndex = i;//和左右端点值进行比较if (l - 1 >= 1 && a[l - 1] > a[maxIndex]) judge = true;if (r + 1 <= n && a[r + 1] > a[maxIndex]) judge = true;if (L < k && !judge) return false;//need removeint need = L % k;ans += need * y;L -= need;//疑问1的解决办法if (y * k >= x) { ans += L / k * x; }else if(judge) { ans += L * y; } else { //其中长度k进行操作1,剩下进行操作2ans += (L - k) * y + x;}return true;
}
int main(){RD(n, m); RD(x, k, y);FOR_1(i, 1, n) RD(a[i]); FOR_1(i, 1, m) RD(b[i]);int i = 1, j = 1;LL ans = 0; //需要花费的魔力值//把b的部分都筛选出来,也就是b的下标j需要走到int p = 0;while(j <= m){while(i <= n && a[i] != b[j]) i++;if (i > n) return printf("-1\n") * 0; //b都没全部得出a就没了,说明存在问题不可能成立,直接-1就好if (!solve(p + 1, i - 1, ans)) return printf("-1\n") * 0;p = i, j++;}if (!solve(p + 1, n, ans)) return printf("-1\n") * 0;printf("%lld\n", ans);}
CF1380D.Berserk And Fireball 【2000】你值得学习的【思维】+【模拟】+【贪心】相关推荐
- 2019 年值得学习的顶级 JavaScript 框架与主题
图:Jon Glittenberg Happy New Year 2019 (CC BY 2.0) 又到了一年的这个时候:JavaScript 年度技术生态回顾.我们的目标是找出最有职业投资回报率的主 ...
- 2020 年最值得学习的 5 大 AI 编程语言
来源:学术头条 本文约1571字,建议阅读4分钟. 本文介绍2020 年最值得学习的 5 大 AI 编程语言,希望对想学习人工智能的读者有帮助. 人工智能是当今世界最具需求的一个领域,人工智能通过编程 ...
- 2015年最值得学习的编程语言是?
2015年最值得学习的编程语言是? 2015-03-04 10:31 来源:优才网 编辑:Loading[纠错]12人评论 A-A+ 怎么开淘宝店 网站优化方法 创业如何获得投资 小米note顶 ...
- 2021年,Java开发者值得学习的13项技能
本文分享自百度开发者中心2021年,Java开发者值得学习的13项技能 作者 | Olivia Cuthbert 译者 | 王强 策划 | 刘燕 如果你想在这个竞争激烈的世界里,成为一名熟练开发 Ja ...
- Github 上 10 个值得学习的 Springboot 开源项目
Spring Boot 几乎继承了所有 Spring 框架的优点,同时还可以让项目的配置更简化.编码更简化.部署更方便.近两年受到很多开发者的追捧,也是火热的不行! 下面给大家整理了 10 个 Git ...
- 圆方圆学院零基础入门学习Python(绝对干货,值得学习)
圆方圆学院零基础入门学习Python(绝对干货,值得学习) 链接: pan.baidu.com/s/1Shpd1G8L- 提取码: bup7
- python工程技巧_python 19个值得学习的编程技巧
Python最大的优点之一就是语法简洁,好的代码就像伪代码一样,干净.整洁.一目了然.要写出 Pythonic(优雅的.地道的.整洁的)代码,需要多看多学大牛们写的代码,github 上有很多非常优秀 ...
- go语言值得学习的开源项目推荐
谷歌官方维护了一个基于go语言的开源项目列表: https://github.com/golang/go/wiki/Projects 其中有非常多的优秀项目值得学习,有几百行代码适合新手阅读的项目,也 ...
- python开源考试_Github 上 10 个值得学习的 Springboot 开源项目
spring Boot 几乎继承了所有 Spring 框架的优点,同时还可以让项目的配置更简化.编码更简化.部署更方便.近两年受到很多开发者的追捧,也是火热的不行! 下面给大家整理了 10 个 Git ...
- Java开发2018年值得学习的10大技术
转载自 Java开发2018年值得学习的10大技术 作为一个开发人员,我们最大的挑战就是保持自己了解新的技术.技术变化很快,你大概每两年就会看到一个新版本的编程语言和框架. 就拿2017年来说,AR. ...
最新文章
- eShopOnContainers 知多少[8]:Ordering microservice
- [转]centos5.2用memcache 来作PHP 的session.save_handler
- mysql的每隔1分钟定时_mysql定时任务
- (转载)做好一个系统分析师、项目经理75条准则(一)
- mysql pkg_Solaris10下mysql的pkg安装方法
- Linux监控命令之==sar
- 奥特曼传奇英雄存档丢了怎么找回_热血传奇复古传奇:传奇游戏手机版竟然比端游还火爆?你觉得呢?...
- CentOS7虚拟机克隆,且成功互ping
- 最大熵图像复原方法原理(附完整代码)
- 程序员基础(自学)适合入门,大一
- PHP LOL接口,教你如何用php实现LOL数据远程获取_PHP教程
- DevOps案例研究|中华有为-解构华为软开云DevOps实践
- 一文盘点中国商业航天:民营火箭的两类瓶颈和三大趋势
- 传祺gac6480_传祺gs82020款,传祺GAC6480J2F5
- SFDC中的DEBUG
- PC-Lint的使用方法
- 计算机xp系统怎么录音,XP系统电脑怎么录音? - KK录像机
- Spring Cloud 统一配置
- mysql 增加主键列_MySQL添加列、删除列,创建主键等常用操作总结
- “永恒之蓝”勒索病毒安全事件应急指导手册(附工具包)
热门文章
- vue中使用微信聊天表情
- 【备读学术论文总览】研究方向论文清单
- 如何查看电脑ip和端口
- chromium编译android,Ubuntu下编译Chromium for Android
- 网站优化:测试网站速度的8款免费工具推荐
- 如何将div拼接成html代码,给div拼接html 拼接字符串
- android一键刷机工具,刷机也能如此轻松 Android一键刷机工具
- 升级opengl和显卡驱动_opengl驱动 OpenGL版本或显卡驱动版本太低的解决方法介绍_网络-游戏圈...
- 推特Twitter API获取关注者名单
- 用Unity同时开发【微信小游戏】【安卓】【IOS】游戏#5.5.1 窗口管理器