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 413 Arithmetic Slices详解
这个开始自己做的动态规划复杂度达到了O(n), 是用的是2维的矩阵来存前面的数据,复杂度太高了, 虽然好理解,但是没效率,后面看这个博客发现没有动态规划做了这个题 也是比较厉害. 转载地址: http ...
- Oracle数据库安装教程
一.准备文件 Oracle安装程序(64位)下载地址: http://download.oracle.com/otn/nt/oracle11g/112010/win64_11gR2_database_ ...
- Eclipse中构建maven项目的两种方式
Eclipse中构建maven项目的两种方式 方式一: 1.构建maven项目 1.1 新建meven项目,可在Other中找到maven文件夹 1.2 进入maven项目后,点击next 1.3 在 ...
- 计算机网络-应用层(1)Web应用与HTTP协议
Web 页面(Web page,也叫文档)是由对象组成的. 对象:HTML文件.JPEG图片.视频文件.动态脚本等,通过一个URL地址寻址.每个URL地址由存放对象的服务器主机名和对象的路径名组成. ...
- python字符串的常见处理方法
python字符串的常见处理方法 方法 使用说明 方法 使用说明 string[start:end:step] 字符串的切片 string.replace 字符串的替换 string.split 字符 ...
- CentOS 6.x/7.x上安装git
yum安装 # yum info git # yum install -y git 可以通过下面的命令来检查是否安装了git环境 git --version 参考:如何在CentOS 6.x/7.x上 ...
- 中文、sci论文写作结构总结
全文建议:30-40篇参考文献,6-8个图,1-3表,<3000词. 一.题目 1.12~15个词,顶多18个词. 2.6个特点:specific.short.impressive.famili ...
- 高并发&性能优化(二)------系统监控工具使用
上一篇主要从总体介绍了高并发&性能优化的相关思路和方法,本篇主要介绍系统监控工具. [CPU查看工具] ------top命令(性能) 进入top命令后,按1即可看到每核CPU的运行指标与详细 ...
- wordpress建站如何用SMTP配置邮件通知
前提条件:你已经有了企业邮箱,相关文章请看:如何开通阿里云企业邮箱免费版(点此前往) 不建议使用主机商提供的邮箱,因为换主机商是比较常见的事情,因此导致的邮箱迁移就有些麻烦了,不如一开始就选择独立的第 ...
- webpack 打包的具体步骤
webpack打包的方法: 方法一 创建一个src文件夹(存放自己的代码),dist文件夹(打包到此文件夹) 2编写自己的代码,在src文件夹中创建一个主模块main.js和若干个js文件,将模块js ...