codeforces Painting the Fence

题目:http://codeforces.com/problemset/problem/1132/C

题意:就是雇佣q-2个画家完成最多的工作;

思路:如果题目要求改成雇佣q-1个画家你会做的话,那么q-2也就可以完成;

           我们枚举不要每一个画家时,从剩下的q-1个画家中删除一个画家的影响所能得到的最大值即可。

刚开始一直想不清楚怎样把两个画家的影响分开算,看了题解后才明白菜是原罪。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 5 * 1000 + 10;
int n, L[maxn], R[maxn],q;

int solve(int id) {
	int num[maxn]; memset(num,0,sizeof(num));		//num[]记录的是每一个画家画的部分前缀
	for (int i = 1; i <= q; i++)if(i!=id)num[L[i]]++, num[R[i] + 1]--;   //当i==id不记录在内即可消除第i个画家的影响
	
	int one[maxn], ans = 0; memset(one,0,sizeof(one));    //One记录的是只由一个画家完成的地方
	for (int i = 1; i <= n; i++) {
		num[i] += num[i - 1];
		if (num[i])ans++; 
		one[i] = num[i] == 1;
	}

	int sum[maxn], c = 0; memset(sum,0,sizeof(sum));     //记录one的前缀和
	for (int i = 1; i <= n; i++)c += one[i], sum[i] += c;

	int res= n+10;
	for (int i = 1; i <= q; i++)if (i != id)res = min(sum[R[i]]-sum[L[i]-1],res);  //sum[R[i]]-sum[L[i]-1]:第i个画家单独完成的数量

	return ans - res;
}

int main() {

	cin >> n>>q;
	
	for (int i = 1; i <= q; i++) {
		scanf("%d%d",L+i,R+i);
	}

	int ans = 0;
	for (int i = 1; i <= q; i++) {   //枚举每一个画家
		ans = max(ans,solve(i));
	}
	
	cout << ans << endl;

	return 0;
}

猜你喜欢

转载自blog.csdn.net/xiaonanxinyi/article/details/88362452

相关文章