题目

题目大意

给你一堆区间,将这些区间分成特定的几个集合,使得每个集合中的所有区间的并不为空。

求最大的每组区间的交的长度之和。


思考历程

一开始就认为这绝对是\(DP\)……

试着找一些性质,结果找不出来……

没办法,只能打个简单的状压\(DP\)……


正解

首先有个很不显然的结论:

对于两个不重合的区间\(a\)和\(b\),如果它们互相包含(即\(l_a\leq l_b<r_b\leq r_a\)),那么一定满足:

  1. \(a\)和\(b\)同在一个组内。
  2. \(b\)在某个组内,而\(a\)单独为一组。

证明:

假设存在这样的情况:\(a\)与其它若干个区间为一组,\(b\)也和其它的区间(或者没有)为一组。

有个很显然的性质,一个区间集合的子集的答案肯定大于等于这个区间的答案。

因为区间交操作只会使得长度越来越小。

所以,如果在这时将\(a\)移到\(b\)的那一组,\(a\)原来的那一组不会更小;并且由于\(a\)包含\(b\),区间交是有交换律的,\(a\)和\(b\)的交还是\(b\),所以\(b\)的那一组的答案不会变。

因此,这种情况是可以被替代的。

证明了这个结论之后就可以搞事情了。

首先,对于区间\(a\),如果它跟某个被它包含的\(b\)一组,那么它并不会有什么贡献;

如果它自己为一组,它才会有贡献,但是这会占掉一个集合的位置。

于是就可以分成两种区间:不包含其它任何区间的区间,和包含了至少一个区间的区间。分别记作\(B\)集合和\(A\)集合。

对于\(B\),如果将所有区间以左端点排序,显然它们的右端点也是有序的。

有了这个优美的性质,分组的时候就是连在一块的区间作为一组。因为这一组的贡献是最左边区间的右端点减去最右边的左端点,如果从连在一块的区间中挖出一个,贡献是不变的。而在这个分组中,很显然我们要在保证贡献最大的同时,消耗的\(B\)集合内的区间尽量多。

设\(f_{i,j}\)为前\(i\)个区间,分成了\(j\)组的贡献。转移显然。

统计答案的时候枚举\(B\)区间分成了几组,对于剩下的还没有分的组,就在\(A\)集合中贪心地选择最大的几个即可。


代码

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 210
int n,ns,nb,p;
struct Range{
int l,r;
} q[N],qs[N];
int qb[N],sum[N];
bool bz[N];
inline bool cmps(Range a,Range b){return a.l<b.l;}
int f[N][N];
inline void upd(int &a,int b){a<b?a=b:0;}
int main(){
// freopen("in.txt","r",stdin);
freopen("factory.in","r",stdin);
freopen("factory.out","w",stdout);
scanf("%d%d",&n,&p);
for (int i=1;i<=n;++i)
scanf("%d%d",&q[i].l,&q[i].r);
for (int i=1;i<=n;++i){
bool b=1;
for (int j=1;j<=n && b;++j)
if (q[i].l<=q[j].l && q[j].r<=q[i].r && !(q[i].l==q[j].l && q[i].r==q[j].r))
b=0;
bz[i]=b;
}
for (int i=1;i<=n;++i)
if (bz[i])
qs[++ns]=q[i];
else
qb[++nb]=q[i].r-q[i].l;
sort(qs+1,qs+ns+1,cmps);
sort(qb+1,qb+nb+1);
reverse(qb+1,qb+nb+1);
for (int i=1;i<=nb;++i)
sum[i]=sum[i-1]+qb[i];
memset(f,128,sizeof f);
f[0][0]=0;
for (int i=1;i<=ns;++i)
for (int k=i-1;k>=0;--k){
if (qs[k+1].r<=qs[i].l)
break;
for (int j=0;j<p;++j)
upd(f[i][j+1],f[k][j]+qs[k+1].r-qs[i].l);
}
int ans=0;
for (int j=0;j<=p;++j)
ans=max(ans,f[ns][j]+sum[p-j]);
printf("%d\n",ans);
return 0;
}

总结

智商还是太低了……

见到区间问题时,要想想各种类似于单调性的问题……

比如包含之类的……

6367. 【NOIP2019模拟2019.9.25】工厂的更多相关文章

  1. 6368. 【NOIP2019模拟2019.9.25】质树

    题目 题目大意 有个二叉树,满足每个点跟它的所有祖先互质. 给出二叉树的中序遍历的点权,还原一种可能的方案. 思考历程 首先想到的当然是找到一个跟全部互质的点作为根,然后左右两边递归下去处理-- 然而 ...

  2. [jzoj 6084] [GDOI2019模拟2019.3.25] 礼物 [luogu 4916] 魔力环 解题报告(莫比乌斯反演+生成函数)

    题目链接: https://jzoj.net/senior/#main/show/6084 https://www.luogu.org/problemnew/show/P4916 题目: 题解: 注: ...

  3. 6424. 【NOIP2019模拟2019.11.13】我的订书机之恋

    题目描述 Description Input Output Sample Input 见下载 Sample Output 见下载 Data Constraint 题解 lj题卡线段树 求出每个右端点往 ...

  4. 6392. 【NOIP2019模拟2019.10.26】僵尸

    题目描述 题解 吼题但题解怎么这么迷 考虑一种和题解不同的做法(理解) 先把僵尸离散化,h相同的钦(ying)点一个大小 (可以发现这样每种情况只会被算正好一次) 计算完全被占领的方案,然后1-方案/ ...

  5. 6389. 【NOIP2019模拟2019.10.26】小w学图论

    题目描述 题解 之前做过一次 假设图建好了,设g[i]表示i->j(i<j)的个数 那么ans=∏(n-g[i]),因为连出去的必定会构成一个完全图,颜色互不相同 从n~1染色,点i的方案 ...

  6. 6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题目描述 题解 随便bb 详细题解见 https://www.cnblogs.com/coldchair/p/11624979.html https://blog.csdn.net/alan_cty/ ...

  7. 6364. 【NOIP2019模拟2019.9.20】养马

    题目描述 题解 一种显然的水法:max(0,-(点权-边权之和*2)) 这样会挂是因为在中途体力值可能会更小,所以考虑求走完每棵子树所需的至少体力值 考虑从子树往上推求出当前点的答案 设每棵子树从根往 ...

  8. 6362. 【NOIP2019模拟2019.9.18】数星星

    题目描述 题解 一种好想/好写/跑得比**记者还快的做法: 对所有询问排序,按照R递增的顺序来处理 维护每个点最后一次被覆盖的时间,显然当前右端点为R时的答案为所有时间≥L的点的权值之和 LCT随便覆 ...

  9. 6359. 【NOIP2019模拟2019.9.15】小ω的树(tree)(定期重构)

    题目描述 题解 qy的毒瘤题 CSP搞这种码农题当场手撕出题人 先按照边权从大到小建重构树,然后40%暴力修改+查找即可 100%可以定期重构+平衡规划,每次把B个询问拉出来建虚树,在虚树上暴力维护每 ...

随机推荐

  1. 【扯淡篇】CTSC/APIO/SDOI R2时在干什么?有没有空?可以来做分母吗?

    注意: 我比较弱, 并没有办法把外链bgm搞成https, 所以大家可以选择"加载不安全的脚本"或者把https改成http以获得更好的阅读体验! 据说, 退役了要写写回忆录. 但 ...

  2. 【模板篇】NTT和三模数NTT

    之前写过FFT的笔记. 我们知道FFT是在复数域上进行的变换. 而且经过数学家的证明, DFT是复数域上唯一满足循环卷积性质的变换. 而我们在OI中, 经常遇到对xxxx取模的题目, 这就启发我们可不 ...

  3. 【CSS】text-align:justify 的使用

    工作需要写一个全是文本的网页,规范格式的时候发现很多css属性不是很熟悉,比如text-align:justify. 这个是两端对齐,css3中新增了text-justify属性 语法:text-ju ...

  4. linux挂载群辉的NFS共享文件夹

    mount -t nfs 192.168.137.136:/volume1/NFSfile /NFSfile -o proto=tcp -o nolock  df -h   #查看挂载点    

  5. kubeadm部署k8s集群

    kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点 kubeadm ini ...

  6. 在linux设置/etc/vimrc 将vim 中后缀.sh的文件 的前几行进行默认输入

    输入vim test.sh 新建后缀sh的文件,效果如下: 具体/etc/vimrc配置为: if expand("%:e") == 'sh'  call setline(1,&q ...

  7. Linux直接在通过终端打开图片文件

    为了提高效率,减少使用鼠标,有时候想直接通过终端的命令打开一个图片进行查看.可以使用的命令有: eog filename display filename 再使用Alt+F4就可以关闭窗口,尽量达到手 ...

  8. Kubernetes 弹性伸缩HPA功能增强Advanced Horizontal Pod Autoscaler -介绍部署篇

    背景 WHAT(做什么) Advanced Horizontal Pod Autoscaler(简称:AHPA)是kubernetes中HPA的功能增强. 在兼容原生HPA功能基础上,增加预测.执行模 ...

  9. Yii2 搜索

    搜索的形式: 第一种,点击空白处: <?php $data=['0'=>'已删除','10'=>'正常','1'=>'锁定']; ?> <table style=' ...

  10. FFT快速傅里叶模板

    FFT快速傅里叶模板…… /* use way: assign : h(x) = f(x) * g(x) f(x):len1 g(x):len2 1. len = 1; while(len < ...