Codeforces 1132 problem C Painting the Fence —— 取n-2个线段的并集最大

2024-04-07 00:32

本文主要是介绍Codeforces 1132 problem C Painting the Fence —— 取n-2个线段的并集最大,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

You have a long fence which consists of n sections. Unfortunately, it is not painted, so you decided to hire q painters to paint it. i-th painter will paint all sections x such that li≤x≤ri.

Unfortunately, you are on a tight budget, so you may hire only q−2 painters. Obviously, only painters you hire will do their work.

You want to maximize the number of painted sections if you choose q−2 painters optimally. A section is considered painted if at least one painter paints it.

Input
The first line contains two integers n and q (3≤n,q≤5000) — the number of sections and the number of painters availible for hire, respectively.

Then q lines follow, each describing one of the painters: i-th line contains two integers li and ri (1≤li≤ri≤n).

Output
Print one integer — maximum number of painted sections if you hire q−2 painters.

Examples
inputCopy
7 5
1 4
4 5
5 6
6 7
3 5
outputCopy
7
inputCopy
4 3
1 1
2 2
3 4
outputCopy
2
inputCopy
4 4
1 1
2 2
2 3
3 4
outputCopy
3

题意:

给你n个线段,让你取其中n-2个,使得他们的并集最大

题解:

真的,不应该看这个标签的。想了好久,交上去以后发现还可以用DP,而且DP代码很短。
我们按左端点为主关键字,右端点为次关键字排序,然后去包含。如果包含的有大于2个,直接输出,如果1个,那么枚举删掉每一个。如果没有覆盖,那么n^2枚举删掉两个的最大值,由于我们是梯度下降的,那么删掉的肯定是只有中间一段了。不会有分开的情况。

#include<bits/stdc++.h>
using namespace std;
const int N=5e3+5;
struct node
{int l,r;bool operator< (const node& a)const{if(l==a.l)return r<a.r;return l<a.l;}
}e[N];
int main()
{int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d",&e[i].l,&e[i].r);int ans=0;sort(e+1,e+1+m);int sum=0,sta=0,en=0;for(int i=1;i<=m;i++){en=max(en,e[i].r);sta=max(sta,e[i].l);while(sta<=en)sum++,sta++;}int maxn=1e5;int all=0,del=0;for(int i=1;i<=m;i++){if(e[i].l>=e[all].l&&e[i].r<=e[all].r)del++;elsee[++all]=e[i];}if(del>=2)return 0*printf("%d\n",sum);if(del>=1){for(int i=1;i<=all;i++){sta=max(e[i-1].r+1,e[i].l);if(i==all)en=e[i].r;elseen=min(e[i].r,e[i+1].l-1);ans=max(ans,sum-max(0,en-sta+1));}return 0*printf("%d\n",ans);}for(int i=1;i<all;i++){maxn=1e5;sta=max(e[i-1].r+1,e[i].l);en=min(e[i].r,e[i+1].l-1);int cut=max(0,en-sta+1);sta=max(e[i-1].r+1,e[i+1].l);if(i+1==m)en=e[i+1].r;elseen=min(e[i+1].r,e[i+2].l-1);maxn=min(maxn,cut+max(0,en-sta+1));for(int j=i+2;j<=all;j++){sta=max(e[j-1].r+1,e[j].l);if(j==m)en=e[j].r;elseen=min(e[j].r,e[j+1].l-1);maxn=min(maxn,cut+max(0,en-sta+1));}ans=max(ans,sum-maxn);}printf("%d\n",ans);return 0;
}

这篇关于Codeforces 1132 problem C Painting the Fence —— 取n-2个线段的并集最大的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/881233

相关文章

关于修改计算机的处理器数和最大内存数的问题

问题描述: 刚开始本来是想让计算机的运行速度运行的快点,于是在网上搜索如何让计算机的运行速度更快,找到了一种关于修改计算机内存数和计算机的处理核数可以让计算机运行的更快。 遇到问题: 当我通过命令msconfig →引导→高级选项→勾选了处理器数和最大内存数,然后重启,结构整个计算机都卡的要死,于是记录下来。网上的答案有时候真的是很不负责任,也有可能是自己技术不到位。 结果:取消处理器和内

Codeforces 158B

很久没有刷题了,刚刚有小学弟问了这道题,AC之后贴上来吧。水~~~ #include <cstdio>#include <cmath>int main() {int n;while(scanf("%d", &n) != EOF) {int a = 0, b = 0, c = 0, d = 0;int arr[100001];for (int i = 0; i < n; ++

Codeforces April Fools Day Contest 2014(附官方题解)

Codeforces2014年愚人节的坑题。。。但还是感觉挺好玩的。。。 A. The Great Game time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Two teams mee

Codeforces April Fools Day Contest 2013

2013年愚人节的坑题。。。 A. Mysterious strings time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Input The input contains a sin

LeetCode 算法:二叉树的最大深度 c++

原题链接🔗:二叉树的最大深度 难度:简单⭐️ 题目 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root = [3,9,20,null,null,15,7] 输出:3 示例 2: 输入:root = [1,null,2] 输出:2 提示: 树中节点的数量在 [0, 104] 区间内。-1

「LeetCode 084」最大面积

题目地址: https://leetcode-cn.com/problems/largest-rectangle-in-histogram/ 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。 example 第一种方法,我们先确定左右两个边界,然后找边界中的最小值。比方说,我们左边界确定

线段树单点修改的应用

思路:对初始状态进行建树,然后这题就相当于查询第一个合法的位置,并且对其值进行修改,整个题目要求维护的是区间最大值,很显然可以使用线段树。 #include <bits/stdc++.h>using namespace std;const int N = 2e6 + 5;typedef long long ll;typedef pair<ll, ll> pll;typedef arra

最大子数组问题(第4章:分治策略)

求子数组的最大和 题目描述: 输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值。要求时间复杂度为O(n)。 例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2, 因此输出为该子数组的和18。   思路 1 当我们加上一个正数时,和会

代码随想录算法训练营day62 | 42. 接雨水、84.柱状图中最大的矩形

42. 接雨水 暴力解法 遍历每根柱子(第一个和最后一个不需要遍历,因为不可能存住水),找到当前柱子的左边最高柱子lHeight,右边最高柱子rHeight,当前柱子能存的水为min(min(lHeight, rHeight) - 当前柱子的高度, 0) class Solution:def trap(self, height: List[int]) -> int:result = 0for

约瑟夫问题(Josephus Problem)4:第k个出列的人是谁

版权所有。所有权利保留。 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/16813419 本文是论述约瑟夫问题的第四部分,约瑟夫问题的描述在第一部分,本文用到了第三部分的算法。请先阅读第一部分和第三部分。 现在要求输出第k个出列的人的编号。 由第三部分的算法分析可知,规模为i-1的队列的任意一人的编号为p,规