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连接,等等都没有 ...
随机推荐
- LeetCode 646 最长数对链详解
题目描述 给出 n 个数对. 在每一个数对中,第一个数字总是比第二个数字小. 现在,我们定义一种跟随关系,当且仅当 b < c 时,数对(c, d) 才可以跟在 (a, b) 后面.我们用这种形 ...
- jieba分词的几种形式
1.精确模式:试图将句子最精确地分开,适合文本分析 seg_list = jieba.cut(test_text, cut_all=False) seg_list = " ".jo ...
- ElasticSearch实战系列七: Logstash实战使用-图文讲解
前言 在上一篇中我们介绍了Logstash快速入门,本文主要介绍的是ELK日志系统中的Logstash的实战使用.实战使用我打算从以下的几个场景来进行讲解. 时区问题解决方案 在我们使用logstas ...
- leetcode刷题记录——栈和队列
题目 232.用栈实现队列 class MyQueue { private Stack<Integer> in = new Stack<>(); private Stack&l ...
- machine vision plan
以OpenCV+C#/C++为主,Halcon+C#/C++.LabVIEW+NI Vision,其他还不了解 目前:Halcon+C# 1.完成:测量定位,表面质量检测 2.完成1后开始:OpenC ...
- git存储用户名和密码
git config --global credential.helper store 输入一次用户名和密码后,git会自动记录用户名密码
- [HDU6793] Tokitsukaze and Colorful Tree
题目 又是一个条历新年,窗前的灼之花又盛开了. 时隔多年,现在只有这一棵树上盛开着残存的 \(n\) 朵灼之花了. 尽管如此,这些灼之 花仍散发出不同色彩的微弱的光芒. 灼之花的生命极为短暂,但它的花 ...
- jsoup中selector的用法及作用
1.jsoup——selector定义: selector选择器是用于对jsoup解析后document文档的数据筛选操作 2.jsoup——selector操作步骤: 1)先导jsoup架包 2)基 ...
- 基于Appium的UI自动化测试
为什么需要UI自动化测试 移动端APP是一个复杂的系统,不同功能之间耦合性很强,很难仅通过单元测试保障整体功能.UI测试是移动应用开发中重要的一环,但是执行速度较慢,有很多重复工作量,为了减少这些工作 ...
- e3mall商城的归纳总结2之认识dubbo、zookeeper
由于本项目用的是soa架构,因此必须需要两个系统之间进行通信,目前的解决办法有三种(本人认为) Webservice:效率不高基于soap协议.项目中不推荐使用. 使用restful形式的服务:htt ...