C. Painting the Fence(思维 + 前缀和)

Problem - C - Codeforces

You需要油漆一个由n个部分组成的长围栏。不幸的是,它没有被涂漆,所以你决定雇用q名画家来完成这项工作。第i名画家将会油漆所有满足lisxsri的部分x.
不幸的是,你的预算很紧,所以你只能雇用q-2名画家。显然,只有你雇用的画家才会完成他们的工作。
如果你选择最优的q-2名画家,你希望最大化已经涂漆的部分数量。如果至少有一名画家对一个部分进行了涂漆,则认为该部分已经涂漆。
输入
第一行包含两个整数n和q (3≤n,q≤5000)--分别是部分数和可供聘用的画家数。
接下来有q行,每行描述其中一位画家:第i行包含两个整数li和ri (1<lisri≤n)。
输出
输出—个整数--如果你雇用q-2名画家,最大可以涂漆的部分数量。

Examples

input

Copy

7 5
1 4
4 5
5 6
6 7
3 5

output

Copy

7

input

Copy

4 3
1 1
2 2
3 4

output

Copy

2

input

Copy

4 4
1 1
2 2
2 3
3 4

output

Copy

3

题解:

首先我们可以记录如果所有人涂,每个点会涂几次,由于数据比较小,差分都不用,直接暴力即可

关键是,我们如何,减去两个人涂的影响呢?

其中一个人我么可以通过,枚举q个人时,让l[i] ~ r[i]这一段区间都减一,这样消去了一个影响,那另一个人呢?

我们这侯就可以用到前缀和了,通过前缀和记录,1~n当前为止,被染的次数1的数量有多少,并且记录n有多少个点被染过,

接着我么枚举i + 1~n,ans = max(ans,sum - pre[r[j]] - pre[l[j]-1]);

通过前缀和可以快速得到,每一段如果不涂的影响(影响就是被涂次数为一的数量)

本题主要考点为,利用前缀和求任意一段得影响(前缀和应用十分广泛的一种思路,不应该想不到的)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
#define int long long
typedef pair<int,int> PII;
int mod = 1e9 + 7;
int l[5005];
int r[5005];
int cnt[5005];
int pre[5005];
void solve()
{
	int n,q;
	cin >> n >> q;
	for(int i = 1;i <= q;i++)
	{
		cin >> l[i] >> r[i];
		for(int j = l[i];j <= r[i];j++)
		cnt[j]++;
	}
	int ans = 0;
	for(int i = 1;i <= q;i++)
	{
		for(int j = l[i];j <= r[i];j++)
		cnt[j]--;
		int sum = 0;
		for(int j = 1;j <= n;j++)
		{
			if(cnt[j] == 1)
			pre[j] = pre[j - 1] + 1;
			else
			pre[j] = pre[j - 1];
			if(cnt[j])
			sum++;
		}
		for(int j = i + 1;j <= q;j++)
		{
			ans = max(ans,sum - (pre[r[j]] - pre[l[j] - 1]));
		}
		
		
		for(int j = l[i];j <= r[i];j++)
		cnt[j]++;
	} 
	cout << ans;
}
//5 7 8 9 10

signed main()
{
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
	int t = 1;
//	cin >> t;
	while(t--)
	{
		solve(); 
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值