洛谷 P7078 - [CSP-S2020] 贪吃蛇(贪心)
题意:
- 有 \(n\) 条蛇,每条蛇有个实力 \(a_i\)
- 我们称编号为 \(x\) 的蛇比编号为 \(y\) 的蛇强,当且仅当 \(a_x>a_y\) 或 \(a_x=a_y\) 且 \(x>y\)。
- 每次实力最强的蛇可以选择吃掉实力最弱的蛇或者不吃,如果实力最强的蛇选择吃,那么它的实力会减去实力最弱的蛇的实力,实力最弱的蛇将消失。
- 假设每条蛇都会选择最优策略(在保证自己不被吃的条件下吃掉尽可能多的别的蛇),问最后会剩下多少条蛇。
- \(\sum n\le 10^7\)
薅洛谷题解 ing
首先我们来挖掘一些性质。可以发现,如果一条蛇吃完最弱的蛇之后不是最弱的蛇,那么它一定会选择吃。因为如果最强的蛇吃完最弱的蛇之后还是最强的蛇,那它不吃白不吃。否则,下一步最强的蛇的实力肯定是弱于原来最强的蛇的实力的,并且由于这条蛇吃完之后不是最弱的蛇,最弱的蛇的实力也强于原来最弱的蛇的实力,也就是说,下一步最强的蛇吃完最弱的蛇之后,肯定比当前最强的蛇吃完最弱的蛇之后的实力更菜,也就是说,如果下一步最强的蛇死了,那它死的时间肯定比当前这条蛇死的时间早,而下一步最强的蛇肯定会选择保住自己,因此下一步最强的蛇一定不会死,故就算这一步最强的蛇吃了最弱的蛇,它也不会死,因此它肯定会选择吃。
那么如果一条蛇吃了最弱的蛇之后变成了最弱的蛇之后怎么办呢?显然,如果一条蛇吃了最弱的蛇之后变成了最弱的蛇,而下一步最强的蛇吃了最弱的蛇之后不是最弱的蛇,或者下一步只剩两条蛇,那它肯定不会吃,因为如果它吃了最弱的蛇,那么下一步最强蛇可以安心吃掉最弱的蛇,它也就挂掉了。
我们再往前回溯一格,如果一条蛇吃了最弱的蛇后,下一步最强的蛇满足之前所述的状态,那么这条蛇会选择吃掉最弱的蛇,因为下一步最强蛇不敢吃最弱的蛇,否则它就会死。因此这一步最强的蛇可以放心大胆地吃,而下一步的蛇又不敢吃,因此这种情况总蛇数会少一。
如果再往前回溯一格那也可以得到类似的结论,如果最强蛇吃完最弱蛇之后回到了上一步所说的状态,那它又不敢吃了,因为吃了之后下一步最强蛇可以安心吃最弱蛇。
我们可以发现,出现最强蛇吃了最弱蛇的情况之后,答案会不会减少一,取决于当前局面到最强蛇能够安心吃掉最弱蛇经过的轮数的奇偶性,如果不算“第一次出现最强蛇吃了最弱蛇变成最弱蛇”这一轮,算上“最强蛇能够安心吃掉最弱蛇”这一轮之后,轮数是偶数,那么答案会减少一。因此我们考虑将整个过程分为两个部分:
- 第一部分:最强蛇吃完最弱蛇之后都不是最弱蛇,放心大胆吃,答案减一
- 第二部分:出现某个最强蛇吃完最弱蛇之后是最弱蛇:重复上面的过程直到出现一条最强蛇可以放心大胆地吃掉最弱蛇,根据第二部分持续的轮数判断答案是否减一。
直接 set 维护大概可以拿到 70 分的好成绩。考虑优化。我们建立两个 deque,分别称作 \(q_1,q_2\),维护现在没有吃过别的蛇,和现在已经吃过别的蛇的蛇的实力,实力从队首到队尾依次递减,然后考虑如下过程:
- 第一部分:
- 每次取出 \(q_1,q_2\) 队尾元素中的较强者作为最强蛇,以及 \(q_1\) 队首元素作为最弱蛇,由于这一部分中所有最强蛇吃完最弱蛇后,都不是最弱蛇,因此这一轮的最弱蛇肯定没有吃过别人,即,在队列 \(q_1\) 中。
- 我们计算出最强蛇吃完最弱蛇的实力,如果小于现在 \(q_1\) 队首的实力就进入第二部分,否则将它塞入 \(q_2\) 队首。根据之前的推论,此时吃完最弱蛇的最强蛇的实力,肯定比上一轮吃完最弱蛇的最强蛇实力更菜。
- 第二部分:
- 我们直接取出 \(q_1,q_2\) 的队尾,由于最弱蛇就是上一轮中吃完最弱蛇的最强蛇,因此我们不用取出 \(q_1/q_2\) 的队首元素,而是直接取出上一次吃掉别人的蛇即可。
- 还是计算出最强蛇吃完最弱蛇的实力,如果此时这条蛇的实力比当前最弱蛇的实力强就退出,根据第二部分轮数的奇偶性判断是否令答案减一。否则继续重复上一步的过程。
时间复杂度 \(\sum n\)。
const int MAXN=1e6;
int n,a[MAXN+5];bool fst=0;
deque<pii> q1,q2;
pii getmx(){
pii p;
if(q1.empty()) return p=q2.back(),q2.ppb(),p;
if(q2.empty()) return p=q1.back(),q1.ppb(),p;
if(q2.back()>q1.back()) return p=q2.back(),q2.ppb(),p;
return p=q1.back(),q1.ppb(),p;
}
void solve(){
if(!fst){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
} else {
int c;scanf("%d",&c);
while(c--){
int x,y;scanf("%d%d",&x,&y);
a[x]=y;
}
} fst=1;
while(!q1.empty()) q1.ppb();
while(!q2.empty()) q2.ppb();
for(int i=1;i<=n;i++) q1.push_back(mp(a[i],i));
// for(int i=1;i<=n;i++) printf("%d%c",a[i]," \n"[i==n]);
while(1){
if(q1.size()+q2.size()<=2) return puts("1"),void();
pii p=getmx();
int y=q1.front().fi;q1.pop_front();
if(q1.empty()||mp(p.fi-y,p.se)<q1.front()){
int cnt=0,res=q1.size()+q2.size()+1,pre=p.fi-y;
while(1){
cnt++;
if(q1.size()+q2.size()<2){
if(cnt&1) res++;
printf("%d\n",res);
return;
} pii nwp=getmx();
if((q1.empty()||mp(nwp.fi-pre,nwp.se)<q1.front())&&
(q2.empty()||mp(nwp.fi-pre,nwp.se)<q2.front()));
else {
if(cnt&1) res++;
printf("%d\n",res);
return;
} pre=nwp.fi-pre;
}
} else q2.push_front(mp(p.fi-y,p.se));
} assert(0);
}
int main(){
// freopen("snakes4.in","r",stdin);
int qu;scanf("%d",&qu);
while(qu--) solve();
return 0;
}
洛谷 P7078 - [CSP-S2020] 贪吃蛇(贪心)的更多相关文章
- 洛谷 P2503 [HAOI2006]均分数据 随机化贪心
洛谷P2503 [HAOI2006]均分数据(随机化贪心) 现在来看这个题就是水题,但模拟赛时想了1个小时贪心,推了一堆结论,最后发现贪心做 不了, 又想了半个小时dp 发现dp好像也做不了,在随机化 ...
- 洛谷P3602 Koishi Loves Segments(贪心,multiset)
洛谷题目传送门 贪心小水题. 把线段按左端点从小到大排序,限制点也是从小到大排序,然后一起扫一遍. 对于每一个限制点实时维护覆盖它的所有线段,如果超过限制,则贪心地把右端点最大的线段永远删去,不计入答 ...
- 洛谷P4155 [SCOI2015]国旗计划(贪心,树形结构,基数排序)
洛谷题目传送门 \(O(n)\)算法来啦! 复杂度优化的思路是建立在倍增思路的基础上的,看看楼上几位巨佬的描述吧. 首先数组倍长是一样的.倍增法对于快速找到\(j\)满足\(l_j+m\le r_i\ ...
- 【题解】洛谷P2577 [ZJOI2005] 午餐(DP+贪心)
次元传送门:洛谷P2577 思路 首先贪心是必须的 我们能感性地理解出吃饭慢的必须先吃饭(结合一下生活) 因此我们可以先按吃饭时间从大到小排序 然后就能自然地想到用f[i][j][k]表示前i个人在第 ...
- BZOJ 2460 & 洛谷 P4570 [BJWC2011]元素 (线性基 贪心)
题目链接: 洛谷 BZOJ 题意 给定 \(n\) 个矿石,每个矿石有编号和魔力值两种属性,选择一些矿石,使得魔力值最大且编号的异或和不为 0. 思路 线性基 贪心 根据矿石的魔力值从大到小排序. 线 ...
- 洛谷 P5470 - [NOI2019] 序列(反悔贪心)
洛谷题面传送门 好几天没写题解了,写篇题解意思一下(大雾 考虑反悔贪心,首先我们考虑取出 \(a,b\) 序列中最大的 \(k\) 个数,但这样并不一定满足交集 \(\ge L\) 的限制,因此我们需 ...
- 【题解】洛谷P1080 [NOIP2012TG] 国王游戏(贪心+高精度)
次元传送门::洛谷P1080 思路 我们模拟一下只有两个大臣的时候发现 当a1∗b1<a2∗b2是ans1<ans2 所以我们对所有大臣关于左右手之积进行排序 得到最多钱的大臣就是 ...
- 洛谷P3817 小A的糖果 贪心思想
一直觉得洛谷的背景故事很....直接题解吧 #include <bits/stdc++.h> //万能头文件 using namespace std; int a[100002]; // ...
- 洛谷P7078 [CSP-S2020] 贪吃蛇 题解
比赛里能做出这题的人真的非常厉害,至少他的智商和蛇一样足够聪明. 首先有一个结论: 当前最强的蛇吃了最弱的蛇之后,如果没有变成最弱的蛇,他一定会选择吃! 证明: 假设当前最强的蛇叫石老板. 如果下一条 ...
随机推荐
- springcloud(二) 微服务架构编码构建
微服务架构编码构建 1 基础知识 1.1 版本 2 微服务cloud整体聚合父工程Project 2.1 new project 2.2 字符编码设置 utf-8 2.3 pom.xml 2.4 父工 ...
- java中this关键字总结
1.this是一个引用,也是一个变量,存储在JVM堆内存的Java对象内部. 2.this变量中保存的内存地址指向自身. 3.this可以在实例方法中使用,this指向当前正在执行这个动作的对象(th ...
- 【二食堂】Beta - Scrum Meeting 3
Scrum Meeting 3 例会时间:5.15 18:30~18:50 进度情况 组员 当前进度 今日任务 李健 1. 继续完成文本区域划词添加的功能 issue 1. 划词功能已经实现,继续开发 ...
- 第32篇-解析interfacevirtual字节码指令
在前面介绍invokevirtual指令时,如果判断出ConstantPoolCacheEntry中的_indices字段的_f2属性的值为空,则认为调用的目标方法没有连接,也就是没有向Constan ...
- 洛谷 P2680 [NOIP2015 提高组] 运输计划
链接:P2680 题意: 在树上把一条边边权变为0使得最长给定路径最短 分析: 最大值最小可以想到二分答案,对于每一个mid,寻找所有大于mid的路径,再寻找是否存在一条边使得删去它后大于mid的路径 ...
- SpringBoot:Spring容器的启动过程
一.简述 Spring的启动过程就是IoC容器的启动过程,本质上就是创建和初始化Bean的工厂(BeanFactory),BeanFactory是整个SpringIoC的核心,Spring使用Bean ...
- 助你上手Vue3全家桶之Vue-Router4教程
目录 1,前言 1,Router 2.1,跳转 2.2,打开新页面 3,Route 4,守卫 4.1,onBeforeRouteLeave 4.2,onBeforeRouteUpdate 4.3,路由 ...
- 问题解决:补充安装c语言的库函数和系统调用man手册
问题解决:补充安装c语言的库函数和系统调用man手册 今日份麻麻~上课时大家的Ubuntu都可以通过man查到关于stat的库函数,但是我的Kali查出来是这样: 询问老师之后得知需要去安装相 ...
- WLAN-无线路由综合应用
一.实验目的 掌握综合应用的配置 二.实验仪器设备及软件 实验仪器设备:路由器.三层交换机.3台二层交换机.AC.3台AP 软件:ensp 三.实验原理 四.实验内容与步骤 AC配置: [AC ...
- Oracle 整库备份还原
http://www.mamicode.com/info-detail-2481866.html sql语句 system用户登陆 查看表空间和存放位置 select t1.name,t2.name ...