[DBSDFZOJ 多校联训] 就
就
背景描述
一排 N 个数, 第 i 个数是 Ai , 你要找出 K 个不相邻的数, 使得他们的和最大。
请求出这个最大和。
输入格式
第一行两个整数 N 和 K。
接下来一行 N 个整数, 第 i 个整数表示 Ai 。
输出格式
一行一个整数表示最大和, 请注意答案可能会超过 int 范围
样例输入
3 2
4 5 3
样例输出
7
数据范围
对于 20% 的数据, N, K ≤ 20 。
对于 40% 的数据, N, K ≤ 1000 。
对于 60% 的数据, N, K ≤ 10000 。
对于 100% 的数据, N, K ≤ 100000 , 1 ≤ Ai ≤ 1000000000。
第一眼看以为是个思博 $DP$ , 然后发现数据范围 $1 \times 10^{5}$ ...一股子 $O(nlog(n))$ 的味道...
一脸懵逼.png
然后就开始各种瞎**优化然后转背包然后就变成了 $60\%$ 的 $O(n^2)$ 算法.
正解果然特么是个贪心.
首先把所有的点都怼进一棵平衡树, 以权值降序第一关键字, 下标升序为第二关键字排序. 然后建立一个链表保存左侧第一个存在结点与右侧第一个存在结点的下标.
然后每次取值最大的元素, 将它和它左右的结点的数据从平衡树中删除, 再把对应的数据改成它的左侧结点与右侧结点的和减去它本身(为了保留不再选取该结点而改选两侧结点的可能性与结果的正确性). 然后修改联保中保存的左侧第二个与右侧第二个元素的右侧/左侧结点下标.
一直贪心 $k$ 次即可得解.总时间复杂度约为 $O(nlog(n))$
参考代码:
#include <set>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #define int long long
const int MAXN=;
const long long INF=0x3FFFFFFFFFFFFFFF; struct Node{
long long value;
int pos;
Node(long long value=,int pos=){
this->value=value;
this->pos=pos;
}
bool friend operator <(const Node &tmp,const Node &y){
return tmp.value!=y.value?tmp.value>y.value:tmp.pos<y.pos;
}
}; int n;
int k;
long long ans;
int next[MAXN];
int front[MAXN];
std::set<Node> s;
long long data[MAXN]; void Initialize();
void Delete(int); signed main(){
Initialize();
while(k--){
int tmp=s.begin()->pos;
ans+=data[tmp];
data[tmp]=data[front[tmp]]+data[next[tmp]]-data[tmp];
s.erase(s.begin());
s.erase(Node(data[front[tmp]],front[tmp]));
s.erase(Node(data[next[tmp]],next[tmp]));
s.insert(Node(data[tmp],tmp));
Delete(tmp);
}
printf("%lld\n",ans);
return ;
} void Delete(int tmp){
if(front[front[tmp]]){
next[front[front[tmp]]]=tmp;
}
if(next[next[tmp]]){
front[next[next[tmp]]]=tmp;
}
front[tmp]=front[front[tmp]];
next[tmp]=next[next[tmp]];
} void Initialize(){
scanf("%lld%lld",&n,&k);
for(int i=;i<=n;i++){
scanf("%lld",data+i);
front[i]=i-;
next[i]=i+;
s.insert(Node(data[i],i));
}
data[]=-INF;
next[n]=;
}
Backup
以及日常图包

[DBSDFZOJ 多校联训] 就的更多相关文章
- [DBSDFZOJ 多校联训] Password
Password password.in/.out 描述 你来到了一个庙前,庙牌上有一个仅包含小写字母的字符串 s. 传说打开庙门的密码是这个字符串的一个子串 t,并且 t 既是 s 的前缀又是 s ...
- Contest1893 - 2019年6月多校联训b层测试1
传送门 密码:waxadyt T1 暴力 对于任意相邻的两个值 中间能到达的最大高度是固定的 加上头尾,判一下就好了 代码//感谢Th Au K #include<bits/stdc++.h&g ...
- 2019西安多校联训 Day5
T1 光哥为了不让某初二奆佬恶心到我们而留下的火种 (貌似没这题平均分就100-了) 思路:就一横一竖让后就gztopa嘛 #include <bits/stdc++.h> using n ...
- 2019西安多校联训 Day4
T1 大水题!!难度简单,显然的贪心策略即可,but... 思路:首先我们按与i点作战后活下来的士兵排序,然后 若当前剩余兵力足够直接减掉战斗死亡人数,如果不够就加 够再打它,但是!我们在考完试观察测 ...
- 2019西安多校联训 Day3
试题链接:http://www.accoders.com/contest.php?cid=1895 考试密码请私信; 特别鸣谢:zkc奆佬帮助我优化本篇题解(语言表达方面) T1 显然二分求解的 ...
- 2019西安多校联训 Day2
试题链接:http://www.accoders.com/contest.php?cid=1894 考试密码请私信; T1 残忍WA 0,明明就是一道非常菜的字符串QAQ 思路:一共找四种东西,A ...
- 2019西安多校联训 Day1
试题链接:http://www.accoders.com/contest.php?cid=1893 考试密码请私信; T1 明明就是O(n)的模拟,强行打成二分QAQ 思路:判断收尾是否为1或 ...
- 三校联训 【NOIP模拟】寻找
题面 “我有个愿望,我希望穿越一切找到你.” 这是个二维平面世界,平面上有n个特殊的果实,我从(0,0)点出发,希望得到尽量多的果实,但是出于某种特殊的原因,我的运动方式只有三种(假设当前我在(x,y ...
- 三校联训 小澳的葫芦(calabash) 题解
题面:小澳的葫芦[ 题目描述]小澳最喜欢的歌曲就是<葫芦娃>.一日表演唱歌,他尽了洪荒之力,唱响心中圣歌.随之,小澳进入了葫芦世界.葫芦世界有 n 个葫芦,标号为 1~ n. n 个葫芦由 ...
随机推荐
- C#控件的Resize事件
1. 当控件大小发生改变时,就会触发该事件 所以适合动态调整UI的布局, 例如: 国际化,不同语言导致控件长度不同: 控件的内容是动态增加的,也可以使用. 2.必须是大小会发生改变的控件才会触发该事件 ...
- linux 升级-杂
apt-cache search linux apt-cache search linux | grep generic apt-cache search linux | grep 4.10. apt ...
- 公司Git实用记录
一.git命令名词解释 1.添加/跟踪/暂存:添加到本地索引 git add 文件名 2.提交:提交到本地仓库 git commit -m '注释' 3.推送:将提交到本地仓库的所有更新提交到服务器 ...
- *2-3-7-加入field_automation机制
在2.3.3节中引入my_mointor时,在my_transaction中加入了my_print函数: 在2.3.5节中引入reference model时,加入了my_copy函数: 在2.3.6 ...
- 2.3.6-加入scoreboard
在验证平台中加入了reference model和monitor之后,最后一步是加入scoreboard.my_scoreboard的代码如下: 代码清单 2-50 文件:src/ch2/sectio ...
- IE7,8纯css实现圆角效果
众所周知,IE7,8不支持border-radius效果.但我们同样有办法用css实现这个效果,方法就是用border来模拟. <!DOCTYPE html> <html lang= ...
- centos下对文件某些特定字符串分组统计出现次数
假如现有数据: { "@timestamp": "2018-10-13T21:55:58+08:00", "remote_addr": &q ...
- Android studio应用导入源码错误This attribute must be localized
This attribute must be localized 产生原因: 多语言错误,源码中关于语言的显示不能直接赋值,而是需要通过xml来实现: 例如 <TextView android: ...
- C#中获取各种路径获取方法
// 获取程序的基目录.System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径,包含文件名System.Diagnostics.Proces ...
- java中接口的定义
使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两部分组成.定义接口的基本格式如下: [修饰符] interface 接口名 [ ...