LG P2389 电脑班的裁员
Description
ZZY有独特的裁员技巧:每个同学都有一个考试得分$a_i(-1000 \leq a_i \leq 1000)$,在$n$个同学$(n \leq 500)$中选出不大于$k$段$(k \leq n)$相邻的同学留下,裁掉未被选中的同学,使剩下同学的得分和最大。要特别注意的是,这次考试答错要扣分【不要问我为什么】,所以得分有可能为负。
Solution
对于$n^3$复杂度:
设$f(i,j)$表示当前选到第$i$个数,选取的段数$\leq j$的最大价值,$s_i$表示前缀和,可以分类讨论:
- $i$不选,则$f(i,j)=f(i-1,j)$
- $i$选,则$f(i, j)=\max \left\{f(k, j-1)+s_{i}-s_{k}\right\}(k < i)$
对于$n^2$复杂度:
设$g(i,j-1)=f(k,j-1)-s_k$,在更新$f$的时候顺便更新$g$,可以做到$n^2$的复杂度
对于$n^2$复杂度:
还有别的思路:
设$f(i,j)$表示当前选到第$i$个数,选取的段数$\leq j$,且$i$不一定选择的最大价值,$g(i,j)$表示当前选到第$i$个数,选取的段数$\leq j$,且$i$一定选择的最大价值
更新$g$时,需要讨论$i-1$是否选择,更新$f$时,需要讨论$i$是否选择:
$$g(i, j)=\max \{g(i-1, j), f(i-1, j-1)\}+a_{i}$$
$$f(i, j)=\max \{g(i, j), f(i-1, j)\}$$
实现时可以滚动数组省去一维,空间复杂度$O(n)$
对于$n\log n$复杂度:
可以贪心
对于一段连续的符号相同的数,只有全部选择或全部不选择两种情况:
- 如果一段负数只选择了一半,就可以找到更大的价值(不选这段负数)
- 如果一段正数只选择了一半,也可以找到更大的价值(同时选择另一段)
所以可以将所有连续的、符号相同的数融合成一个数
设当前序列中正数的个数为$cnt$
- $cnt \geq k$时,选择最大的$k$个正数
- $cnt < k$时,需要做出一些放弃
要么选择一个负数,将两个正数连接在一起;要么放弃一个正数
不论哪一种选择,选择对数$x$进行操作,损失的价值都为$|x|$
使用优先队列可以实现
对于$n$复杂度:
贪心还可以改进
假设当前还需要合并$m$个数,那么:
- 大小小于第$m$大的必定要被合并
- 大小大于第$3m$大的必定不会被合并
- 每一轮合并至少合并了$\frac m3$个数
每次合并将三个数合并为一个,所以合并$m$个数最多会影响$3m$个数,假如每次影响的三个数大小都为小于第$m$大,就会合并$\frac m3$个数
总时间复杂度:$n+\frac{2}{3} n+\left(\frac{2}{3}\right)^{2} n+\ldots$
#include<algorithm>
#include<iostream>
#include<utility>
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;
int n,k,l[],r[],l1[],r1[],tot,cnt;
long long ans,a[];
bool del[],del1[],in[];
queue<long long>q;
pair<long long,int>t[],minn,maxx;
inline int read()
{
int f=,w=;
char ch=;
while(ch<''||ch>'')
{
if(ch=='-')
f=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
w=(w<<)+(w<<)+ch-'';
ch=getchar();
}
return f*w;
}
void delet1(int x)
{
if(x)
{
int L=l1[x],R=r1[x];
l1[R]=L;
l1[L]=R;
del1[x]=true;
}
}
void delet(int x)
{
if(x)
{
--tot;
int L=l[x],R=r[x];
l[R]=L;
r[L]=R;
del[x]=true;
delet1(x);
}
}
void add(int x)
{
if(x&&pair<long long,int>(abs(a[x]),x)<=minn)
{
in[x]=true;
q.push(x);
}
}
void merge(int x)
{
if(del[x])
{
return;
}
int L=l[x],R=r[x];
if(L&&abs(a[L])<abs(a[x]))
{
return;
}
if(R&&abs(a[R])<abs(a[x]))
{
return;
}
delet(L);
delet(R);
a[x]+=a[L]+a[R];
if(L&&R)
{
add(x);
}
else
{
delet(x);
} }
int main()
{
n=read();
k=read();
for(int i=;i<=n;i++)
{
int x=read();
if(!x)
{
continue;
}
if(x<&&!tot)
{
continue;
}
if(tot&&a[tot]<==x<)
{
a[tot]+=x;
}
else
{
a[++tot]=x;
}
}
if(tot&&a[tot]<)
{
--tot;
}
for(int i=;i<=tot;i++)
{
l[i]=l1[i]=(i+tot)%(tot+);
r[i]=r1[i]=(i+)%(tot+);
}
while(tot>k*-)
{
cnt=;
for(int i=r1[];i;i=r1[i])
{
if(!del1[i])
{
t[++cnt]=pair<long long,int>(abs(a[i]),i);
}
}
int temp=(tot-(k*-))>>;
nth_element(t+,t+min(cnt,temp),t+cnt+);
minn=t[min(cnt,temp)];
nth_element(t+,t+min(cnt,*temp),t+cnt+);
maxx=t[min(cnt,*temp)];
for(int i=r1[];i;i=r1[i])
{
pair<long long,int> p(abs(a[i]),i);
if(p>maxx)
{
delet1(i);
}
else
{
add(i);
}
}
while(q.size())
{
int u=q.front();
q.pop();
in[u]=false;
merge(u);
}
}
for(int i=r[];i;i=r[i])
{
if(a[i]>)
{
ans+=a[i];
}
}
printf("%lld\n",ans);
return ;
}
电脑班的裁员
LG P2389 电脑班的裁员的更多相关文章
- 洛谷P2389 电脑班的裁员(区间DP)
题目背景 隔壁的新初一电脑班刚考过一场试,又到了BlingBling的裁员时间,老师把这项工作交给了ZZY来进行.而ZZY最近忙着刷题,就把这重要的任务交(tui)给了你. 题目描述 ZZY有独特的裁 ...
- P2389 电脑班的裁员 (动态规划)
题目背景 隔壁的新初一电脑班刚考过一场试,又到了BlingBling的裁员时间,老师把这项工作交给了ZZY来进行.而ZZY最近忙着刷题,就把这重要的任务交(tui)给了你. 题目描述 ZZY有独特的裁 ...
- 洛谷 P2389 电脑班的裁员 解题报告
题意: 给定一段长为N的序列,选取其中的至多M段使这些子段和最大. 当N=1000时,我们可以采用动态规划解法 令\(dp[i][j][k]\)代表当前选至位置\(i\)处于第\(j\)段当前是否选取 ...
- P2389 电脑班的裁员
题意:长度为n的序列,选出k个连续的字段,使和最大(有负数) 暴力只选正数且不考虑k的边界问题50(数据...) 正解从$O(n^3)到O(n)$不等,($O(n)$不会) DP 1.$O(n^3)$ ...
- 【Luogu】P2389电脑班的裁员(DP)
题目链接 sbt交了三遍才过是我的耻辱…… 就是设f[i][j]搞个三重循环DP一下,以上. #include<cstdio> #include<cstdlib> #inclu ...
- Linux下安装性能测试负载机LG
系统:CentOS release 6.6 (Final) x86_64 安装包: 1.LRLG_00031.iso [Load Generator Standalone (Linux 64-bit ...
- bootstrap 之 xs,sm,md,lg && 主要颜色
mobile – xs ( <768px ) tablet – sm ( 768~991px ) desktop – md ( 992~1170px ) large desktop – lg ( ...
- boostrap中lg,md,sm,xs
boostrap中lg,md,sm,xs分别表示多少px? .col-xs- 超小屏幕 手机 (<768px).col-sm- 小屏幕 平板 (≥768px).col-md- 中等屏幕 桌面显示 ...
- LG 2.2.1 P350安卓系统刷机,问题总结,希望对需要的朋友有助
手机误删软件导致短信,键盘等无声音提醒 我的手机前几天被我误删了一个软件,导致电话接不了,别人打电话的时候,老提示我在通话中,但是我可以在通话中看到对方的打电话记录.短信,键盘,USB连接,等等都没有 ...
随机推荐
- 【IDE】WebStorm 调整Tab缩进为2空格 -- 为遵循ESLint语法规范
步骤一 修改这三处的值为:2 步骤二 把这两处默认的勾选去掉,不让其detection当前文件的Tab缩进 注意! 通过上面两个步骤,我们只是改变了在JS文件的Tab缩进改为2个空格 但是,*.vue ...
- HahMap(jdk=1.8)源码解读
简介:岁月磨平了人的棱角,让我们不敢轻易的去放手,即使它在你心中并不那么重要,你依旧害怕失去它,不是舍不得,是内心的迷茫. 一 : 创建HashMap HashMap<Object, Objec ...
- Golang Gtk+3教程:开始
GTK+是一个控件工具包.每个通过GTK+创建的用户界面由一些控件组成. 控件是层级式的,window控件是主容器,通过在window中添加按钮.下拉菜单.输入字段等其他控件构成用户界面. 如果是复杂 ...
- G4560 HD610安装黑苹果Hakintosh
这一篇主要是写给使用G4560笔记本折腾黑苹果的朋友. 我折腾了几天黑苹果,发现怎么也无法成功,最后我才知道HD610现在还不支持黑苹果. 由于大多数笔记本不支持屏蔽核显,这意味着要想使用黑苹果必须要 ...
- Ubuntu 16.04 sudo免密码visudo sudoers设置
使用sudo visudo调用nano对 /etc/sudoers 进行修改 $ sudo visudo 在想修改的对象最后加上 NOPASSWD: ALL 注意:在后面的设置会覆盖前面的设置
- Python Unofficial Windows Binary
python一些安装包有时候在windows下无法 直接安装. 可以在一个非官方的Python Windows扩展库里面找到对应的打包好的whl,下载后直接安装. https://www.lfd.uc ...
- 从零开始讲解JavaScript中作用域链的概念及用途
从零开始讲解JavaScript中作用域链的概念及用途 引言 正文 一.执行环境 二.作用域链 三.块级作用域 四.其他情况 五.总结 结束语 引言 先点赞,再看博客,顺手可以点个关注. 微信公众号搜 ...
- 第5篇 Scrum冲刺博客
1.站立式会议 1.1 会议图片 1.2 项目进展 成员 昨日任务 今日计划完成任务 陈忠明 歌曲信息的上传/下载包 歌曲批量下载压缩包 吴茂平 完善评论系统 新消息提醒功能设计 黄海钊 修改代码规范 ...
- 自己搭建的集群,启动hadoop时slave节点的datanode没有启起来怎么办?
自己搭建的集群,启动hadoop 集群是,发现slave节点的datanode没有启动,查了资料发现是因为我在启动集群前,执行了这个命令: hadoop namenode -format 这个指令会重 ...
- Python趣味入门5:循环语句while
跟着小牛叔,找准正确编程入门姿势,每天只要阅读10分钟. 任何语言都有循环语句,在Python里循环更是变化无穷,有基本的循环,有循环else语句,引伸出来的还有迭代器.推导式,咱们先学习最简单的一种 ...