题目

你知道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. yum基本使用方法

    yum 是 Fedora RHEL Centos SUSE等linux 发行版的 软件包管理工具 通过 执行 man yum 查看yum的帮助信息 可以知道 yum makecache 是将服务器上的 ...

  2. java通过jna调用so

    c++: FirstEliteValidate.h #pragma once void __attribute__((constructor)) startup();void __attribute_ ...

  3. html的标签规范

    if/else标签{ % if condition1 %} ... display 1{ % elif conditon2 %} ... display 2{ % else % } ... displ ...

  4. 【计算机视觉】HDR之tone mapping简介

    tone Mapping原是摄影学中的一个术语,因为打印相片所能表现的亮度范围不足以表现现实世界中的亮度域,而如果简单的将真实世界的整个亮度域线性压缩到照片所能表现的亮度域内,则会在明暗两端同时丢失很 ...

  5. 关于migration build failed的问题

    首先一定要执行dotnet restore 查看网站的依赖关系(有时候生成是不报错的但是restore会找不到文件路径) 检查执行命令的路径是否是正确的当前网站路径 build failed一定是生成 ...

  6. Canvas入门02-绘制直线

    主要使用的API有: context.moveTo(x,y) 声明线的起始坐标 context.lineTo(x,y) 声明线的下一个坐标 context.fillStyle  声明线的填充颜色 co ...

  7. js 自调函数

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. uwsgi + nginx 部署python项目(一)

    uWSGI uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换. 要注意 WSGI / uws ...

  9. Java第三周课程总结&实验报告一

    第三周课程总结 1.关于面向对象的一些具体内容,明白了类与对象以及Java的封装性和构造方法以及对对象匿名的相关知识. 2.this关键字,它是表示类的成员属性(变量),使用this构造方法时必须放在 ...

  10. PHP_OS的常见值

    PHP_OS是PHP中的一个预定义常量,表示当前操作系统.那么PHP_OS有哪些值可用呢??PHP_OS的值一般可以为:CYGWIN_NT-5.1,Darwin,FreeBSD,HP-UX,IRIX6 ...