题目

你知道Just Odd Inventions社吗?这个公司的业务是“只不过是奇妙的发明(Just Odd Inventions)”。这里简称为JOI社。

JOI社有N名员工,编号从1到N。所有员工的工作时间从时刻0持续到时刻M,时刻0和时刻M的时候,所有员工都必须在公司内。

某天,出于巧合,JOI社的每个员工都要出行恰好一次。员工i(1<=i<=N)在时刻Si离开公司,时刻Ti回到公司。同一时刻不会同时有两名以上的员工离开或回到公司。

JOI社的入口处有一扇巨大的门,员工只能通过这扇门离开或回到公司。门上挂着一把锁,从公司内部可以任意开锁或上锁,但从公司外部只有持有备用钥匙的人才能开锁或者上锁。时刻0时,锁是锁上的。

每个社员在回到公司的时候,都必须能够进入公司。换句话说,对于任意1<=i<=N,要么员工i持有备用钥匙,要么时刻Ti时门是开着的,否则是不被允许的。员工回到公司的时候,或者携带备用钥匙的员工离开公司的时候,可以选择锁门或不锁。没有携带备用钥匙的员工离开公司的时候没有办法锁门。

JOI社的社长决定把备用钥匙交给N个员工中的K个人。为了避免钥匙的丢失,员工之间不允许借用钥匙。此外,JOI社的社长很重视时间效率,因此每个员工在离开或回到公司的时刻以外,不允许开锁或者上锁。

出于安全的考虑,社长希望上锁的时间越长越好。现在他将员工出入公司的信息和准备交给员工的钥匙数量告诉了你,请你求出在能使所有员工回到公司的时候都能进入公司的大门的前提下,上锁的时间最长是多少。

分析

首先把所有进出时间都放在坐标系下,发现相邻的两个点会有4种情况:

第一种:左出右出

只需要左端点那个人带钥匙该区间便可以获得其中的值。

第二种:左进右进

右端点那个人带钥匙该区间便可以获得其中的值。

第三种:左进右出

都不用拿,直接计入答案。

第四种:左出右进

两人都带钥匙该区间便可以获得其中的值。

对于前两种情况,设v[i]表示当i这个人拿了钥匙时,可以给答案贡献多少;

而第四种情况,可以将两个人连一条边,然后就会发现很多个联通块,而且都是以一条链的形式。

然后,所有的链排在一起,给每一个点按位置一个新的编号。

问题转化为,有n个点,选取每个点有得分,并且同时选取一个点以及它的上一个点有额外得分,求选出k 个点的最高得分。

就可以用dp解决:

f[i][j]表示前i个点,选了j个点,其中包括i,的最大得分;

f[i][j]=max(max(f[1~i-2][j-1]),f[i-1][j-1]+当选取了i-1和i时可以获得的额外得分)+v[i]

其中max(f[1~i-2][j-1])可以开一个动态数组表示:

g[j]表示当前做到i的max(f[1~i-2][j])。

然后就变成了

f[i][j]=max(g[j-1],f[i-1][j-1]+当选取了i-1和i时可以获得的额外得分)+v[i]

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
using namespace std;
int g[4005],v[4005],tog[4005],f[4005][4005],b[4005][5],n,m,tot,ans,k,mx,d[4005],next[4002];
bool bz[4002];
void q(int l,int r)
{
int i=l,j=r,mid=b[(l+r)/2][2],e;
while(i<j)
{
while(b[i][2]<mid) i++;
while(b[j][2]>mid) j--;
if(i<=j)
{
e=b[i][2];
b[i][2]=b[j][2];
b[j][2]=e;
e=b[i][0];
b[i][0]=b[j][0];
b[j][0]=e;
e=b[i][1];
b[i][1]=b[j][1];
b[j][1]=e;
i++;
j--;
}
}
if(i<r) q(i,r);
if(l<j) q(l,j);
}
int dg(int x)
{
if(!x)
return 0;
bz[x]=false;
dg(next[x]);
d[d[0]--]=x;
}
int main()
{
int i;
scanf("%d%d%d",&n,&m,&k);
tot=0;
for(i=1;i<=n;i++)
{
scanf("%d",&b[++tot][2]);
b[tot][1]=i;
b[tot][0]=0;
scanf("%d",&b[++tot][2]);
b[tot][1]=i;
b[tot][0]=1;
}
q(1,tot);
ans=0;
memset(bz,true,sizeof(bz));
for(i=1;i<=tot-1;i++)
{
int x=b[i][0]*10+b[i+1][0];
if(x==0)
{
v[b[i][1]]+=b[i+1][2]-b[i][2];
}
else
if(x==11)
{
v[b[i+1][1]]+=b[i+1][2]-b[i][2];
}
else
if(x==10)
{
ans+=b[i+1][2]-b[i][2];
}
else
{
if(b[i][1]!=b[i+1][1])
{
next[b[i][1]]=b[i+1][1];
bz[b[i+1][1]]=false;
tog[b[i+1][1]]=b[i+1][2]-b[i][2];
}
else
{
v[b[i][1]]+=b[i+1][2]-b[i][2];
}
}
}
ans+=b[1][2];
ans+=m-b[tot][2];
d[0]=n;
for(i=1;i<=n;i++)
if(bz[i])
dg(i);
for(i=1;i<=n;i++)
{
for(int j=1;j<=k;j++)
{
if(j>1)
f[i][j]=max(g[j-1],f[i-1][j-1]+tog[d[i]]);
f[i][j]+=v[d[i]];
g[j]=max(g[j],f[i-1][j]);
mx=max(mx,f[i][j]);
}
}
printf("%d\n",mx+ans);
}

【NOIP2015模拟11.3】备用钥匙的更多相关文章

  1. JZOJ 4298. 【NOIP2015模拟11.2晚】我的天

    4298. [NOIP2015模拟11.2晚]我的天 (File IO): input:ohmygod.in output:ohmygod.out Time Limits: 1000 ms Memor ...

  2. 【NOIP2015模拟11.5】JZOJ8月5日提高组T2 Lucas的数列

    [NOIP2015模拟11.5]JZOJ8月5日提高组T2 Lucas的数列 题目 PS:\(n*n*T*T<=10^{18}\)而不是\(10^1*8\) 题解 题意: 给出\(n\)个元素的 ...

  3. 【NOIP2015模拟11.5】JZOJ8月5日提高组T1 俄罗斯套娃

    [NOIP2015模拟11.5]JZOJ8月5日提高组T1 俄罗斯套娃 题目 题解 题意就是说 将1~\(n\)排列,问有多少种方案使得序列的逆序对个数小于\(k\) 很容易想到DP 设\(f[i][ ...

  4. 【NOIP2015模拟11.2晚】JZOJ8月4日提高组T2 我的天

    [NOIP2015模拟11.2晚]JZOJ8月4日提高组T2 我的天 题目 很久很以前,有一个古老的村庄--xiba村,村子里生活着n+1个村民,但由于历届村长恐怖而且黑暗的魔法统治下,村民们各自过着 ...

  5. 【NOIP2015模拟11.4】JZOJ2020年8月6日提高组T2 最优交换

    [NOIP2015模拟11.4]JZOJ2020年8月6日提高组T2 最优交换 题目 题解 题意 有一个长度为\(n\)的正整数 最多可以进行\(k\)次操作 每次操作交换相邻两个位置上的数 问可以得 ...

  6. 【NOIP2015模拟11.4】JZOJ8月6日提高组T1 刷题计划

    [NOIP2015模拟11.4]JZOJ8月6日提高组T1 刷题计划 题目 题解 题意 有\(n\)道题,编号为1~\(n\) 给出\(m\)次操作 每次操作有3种类型 1 \(x\) 表示交了\(A ...

  7. 【NOIP2015模拟11.5】JZOJ8月5日提高组T3 旅行

    [NOIP2015模拟11.5]JZOJ8月5日提高组T3 旅行 题目 若不存在第\(k\)短路径时,输出"Stupid Mike" 题解 题意 给出一个有\(n\)个点的树 问这 ...

  8. JZOJ4307. 【NOIP2015模拟11.3晚】喝喝喝

    Description

  9. [JZOJ 4307] [NOIP2015模拟11.3晚] 喝喝喝 解题报告

    题目链接: http://172.16.0.132/senior/#main/show/4307 题目: 解题报告: 题目询问我们没出现坏对的连续区间个数 我们考虑从左到有枚举右端点$r$,判断$a[ ...

随机推荐

  1. yarn.lock 是干什么的

    概述 今天本地运行尤大的vue-hackernews-2.0,使用 yarn 命令安装,报错提示 node 版本必须大于7小于9,如下所示: error upath@1.0.4: The engine ...

  2. Shiro Demo 示例(SpringMVC-Mybatis-Shiro-redis)

    Shiro Demo 准备工作 运行前申明 请看完本页面的所有细节,对你掌握这个项目来说很重要,别一上来就搞,你不爽,我也不爽. 本项目需要一定的Java功底,需要对SpringMvc,Mybatis ...

  3. Linux 下创建静态库和动态库

    1.创建静态链接库 2.创建动态链接库

  4. struts2 2.5.16 通配符方式调用action中的方法报404

    1.问题描述 在struts.xml中配置用通配符方式调用action中的add()方法,访问 http://localhost:8080/Struts2Demo/helloworld_add.act ...

  5. 【FICO系列】SAP FICO总账余额相关的事务码

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[FICO系列]SAP FICO总账余额相关的事 ...

  6. unity监听粒子播放结束

    需要在粒子上挂脚本 脚本添加代码 public void OnParticleSystemStopped() { Debug.Log("粒子停止"); } 这是个生命周期 粒子的 ...

  7. MySQL的count(*)性能怎么样?

    对于count(主键id)来说,innodb引擎会遍历整张表,把每一行的id值都取出来,返回给server层,server层判断id值不为空,就按行累加 对于count(1)来说,innodb引擎遍历 ...

  8. python字符串-方法

    一.1. upper()作用:将字符串中字符转换为大写 In [17]: spam Out[17]: 'hello,world' In [18]: print(spam.upper()) HELLO, ...

  9. Clover的简单使用

    官网: http://cn.ejie.me 操作说明相关: 方便的 Tab 页功能 要掌握功能强大,操作简单的标签页,只需记住Ctrl+T新开页面,Ctrl+W关闭页面,Ctrl+Tab切换页面,工作 ...

  10. IDEA 快捷键 (长期更新)

    自动清除无效 import 和 清除无效 import  ctrl+alt+o