首先注意一下题面要求,使得选出的线段两两要么包含要么不相交,也就是说一条线段可能会出现不相交的几条线段,而这些线段上面也可能继续这样包含线段。然后我们可以发现我们要做的实际上是在这条线段上选取几条线段然后递归求出子问题,这是一个 \(dp\) 的形式,令 \(f_i\) 表示在线段 \(i\) 上最多能选出多少个满足条件的区间。但是在这里拓扑序我们还未知,我们看看能否求出这个 \(dp\) 的拓扑序。我们发现对于任意一条线段我们能选择被它包含的线段必然左端点大于该线段左端点,右端点大于该线段左端点,那么我们只需要按照右端点排序,那么每次能转移到的区间就都会已经计算完毕。但需要注意的是如果右端点相同,我们还要按照左端点从大到小排序,这样才能保证小的线段先算。

接下来考虑如何转移,实际上这里需要求解的一个问题就是每个线段有一个权值,选出一些不相交的线段使得它们的权值最大。接下来可以发现如果当前线段能选,那么上次选的最右边线段的右端点一定要比当前线段的左端点要靠前,于是可以令 \(dp_i\) 表示当前选择的最右边的右端点在 \(i\) 的最大权值,有转移:

\[dp_{a_i.r} = \max\{dp_{a_j.r} + f_i\}(a_j.r < a_i.l)
\]

将 \(f_i\) 拉出来这就是一个前缀 \(\max\) 的形式,因为右端点是单调递增的,因此只需要沿途维护一个指针扫过来并统计即可。本题当中值域很大?可以发现我们只关注大小关系,离散化即可。

#include<bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for(int i = l; i <= r; ++i)
const int N = 6000 + 5;
struct node{
int l, r;
}a[N];
int T, n, tot, cnt, f[N], g[N], d[N], dp[N];
int read(){
char c; int x = 0, f = 1;
c = getchar();
while(c > '9' || c < '0'){ if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
bool cmp(node a, node b){
return a.r == b.r ? a.l > b.l : a.r < b.r;
}
int main(){
T = read();
while(T--){
n = read(), tot = 0;
rep(i, 1, n) a[i].l = read(), a[i].r = read(), d[++tot] = a[i].l, d[++tot] = a[i].r;
sort(d + 1, d + tot + 1), sort(a + 1, a + n + 1, cmp);
cnt = unique(d + 1, d + tot + 1) - d - 1;
rep(i, 1, n){
a[i].l = lower_bound(d + 1, d + cnt + 1, a[i].l) - d;
a[i].r = lower_bound(d + 1, d + cnt + 1, a[i].r) - d;
}
rep(i, 1, n){
int P = 0, l = 0;
rep(j, 1, a[i - 1].r) dp[j] = g[j] = 0;
rep(j, 1, i - 1) if(a[j].l >= a[i].l){
if(a[j].r != l) ++P;
while(P < a[j].r) g[P] = g[P - 1], ++P;
dp[a[j].r] = max(dp[a[j].r], g[a[j].l - 1] + f[j]), g[P] = max(g[P - 1], dp[a[j].r]);
l = a[j].r;
}
f[i] = g[P] + 1;
}
int P = 0, l = 0;
rep(i, 1, a[n].r) dp[i] = g[i] = 0;
rep(i, 1, n){
if(a[i].r != l) ++P;
while(P < a[i].r) g[P] = g[P - 1], ++P;
dp[a[i].r] = max(dp[a[i].r], g[a[i].l - 1] + f[i]), g[P] = max(g[P - 1], dp[a[i].r]);
l = a[i].r;
}
printf("%d\n", g[a[n].r]);
rep(i, 1, a[n].r) dp[i] = f[i] = g[i] = 0;
}
return 0;
}

CF1399F Yet Another Segments Subset的更多相关文章

  1. Array and Segments (Easy version) CodeForces - 1108E1 (暴力枚举)

    The only difference between easy and hard versions is a number of elements in the array. You are giv ...

  2. CodeForces - 1101G :(Zero XOR Subset)-less(线性基)

    You are given an array a1,a2,…,an of integer numbers. Your task is to divide the array into the maxi ...

  3. Codeforces Round #535 (Div. 3) E2. Array and Segments (Hard version) 【区间更新 线段树】

    传送门:http://codeforces.com/contest/1108/problem/E2 E2. Array and Segments (Hard version) time limit p ...

  4. codeforces 1101G (Zero XOR Subset)-less 前缀异或+线性基

    题目传送门 题意:给出一个序列,试将其划分为尽可能多的非空子段,满足每一个元素出现且仅出现在其中一个子段中,且在这些子段中任取若干子段,它们包含的所有数的异或和不能为0. 思路:先处理出前缀异或,这样 ...

  5. Codeforces 1108E2 Array and Segments (Hard version) 差分, 暴力

    Codeforces 1108E2 E2. Array and Segments (Hard version) Description: The only difference between eas ...

  6. [LeetCode] Number of Segments in a String 字符串中的分段数量

    Count the number of segments in a string, where a segment is defined to be a contiguous sequence of ...

  7. [LeetCode] Partition Equal Subset Sum 相同子集和分割

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  8. [LeetCode] Largest Divisible Subset 最大可整除的子集合

    Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of ...

  9. Greenplum记录(一):主体结构、master、segments节点、interconnect、performance monitor

    结构:Client--master host--interconnect--segment host 每个节点都是单独的PG数据库,要获得最佳的性能需要对每个节点进行独立优化. master上不包含任 ...

随机推荐

  1. Chapter 6 Graphical Representation of Causal Effects

    目录 6.1 Causal diagrams 6.2 Causal diagrams and marginal independence 6.3 Causal diagrams and conditi ...

  2. MySQL数据库基础(1)数据库基础

    目录 一.数据库简介 二.mysql数据库 三.客户端连接mysql服务 四.Navicat for mysql 一.数据库简介 1.概念 (1)数据:如文字.图形.图像.声音以及学生的档案记录等,这 ...

  3. 编写Java程序,车站只剩 50 张从武汉到北京的车票,现有 3 个窗口售卖,用程序模拟售票的过程,使用Runnable解决线程安全问题

    查看本章节 查看作业目录 需求说明: 车站只剩 50 张从武汉到北京的车票,现有 3 个窗口售卖,用程序模拟售票的过程,要求使用同步方法保证售票过程中票数的正确性 实现思路: 创建 Java 项目,在 ...

  4. Kibana_X-Pack管理Elasticsearch权限

    在Kibana上面配置权限,验证对Elasticsearch权限控制, 主要步骤如下: 1.创建角色 2.创建用户,并且赋予用户角色 3.用户登陆,验证没有权限 4.赋予角色权限 5.用户登陆,验证拥 ...

  5. LDAP客户端安装

    安装环境: 10.43.159.7 客户端 使用ldap客户端验证登陆: 用户为10.43.159.9服务端上面创建的ldap:zdh1234 1.安装LDAP client认证需要的pam包 yum ...

  6. 使用sudo执行命令提示command not found

    笔记: 使用源码部署nginx的时候,使用sudo nginx提示command not found,但是直接使用nginx会导致权限问题: 这种情况应该是环境变量导致的,使用 env |grep P ...

  7. python 面向对象:多态和多态性

    很多人喜欢将多态与多态性二者混为一谈,然后百思不得其解,其实只要分开看,就会很明朗. 一.多态 多态指的是一类事物有多种形态.(一个抽象类有多个子类,因而多态的概念依赖于继承) 比如动物有多种形态:人 ...

  8. 物理机异常断电,linux虚拟机系统磁盘mount失败,导致无法启动; kubectl 连接失败

    虚拟机 CentOS 7 挂载文件系统失败 上周五下班前没有关闭虚拟机和物理机, 今天周一开了虚拟机之后,发现操作系统启动失败. 原因跟 这篇文章描述的一模一样. 解决操作系统的文件系统挂载的问题之后 ...

  9. 使用Eclipse新建项目

    如果图片损坏,点击查看: https://www.toutiao.com/i6496078011538866702/ 出现"新建"对话框,输入mavem 点击创建"简单M ...

  10. hadoop入门到实战(6)hive常用优化方法总结

    问题导读:1.如何理解列裁剪和分区裁剪?2.sort by代替order by优势在哪里?3.如何调整group by配置?4.如何优化SQL处理join数据倾斜?Hive作为大数据领域常用的数据仓库 ...