Codeforces1132 C 思维 难

https://codeforces.com/contest/1132/problem/C
给一个长度为n的区间 q个工人
每个工人染一个区间 只用q-2个工人 最多有多少个区间被染色

可以考虑删除2个工人 能保留最多被染色的区间
n,q<=5000 O(n2)
开始1-q 枚举先删除一个区间 vis数组计数–
先标记只有1个工人染色的区间
同时统计删除1个区间后还剩几个区间被染色tot 每次清0
num[i] 前缀和表示从1-i 只染一次的区间数量
枚举除先删除的区间外其他区间 删掉l[j]->r[j]的只染1次的区间数
染色超过1次对答案无影响
tot-(num[r[j]]-num[l[j]-1]) 取最大值
最后还原vis数组数量++

int n,q,cnt0,cnt1,cnt,res;
int l[5005],r[5005],vis[5005],book[5005],num[5005];
int main(){
	cin>>n>>q;
	rep(i,1,q){
		cin>>l[i]>>r[i];
		for(int j=l[i];j<=r[i];j++){
			vis[j]++;
		}

	}
	for(int i=1;i<=n;i++){
		if(vis[i])
			cnt++;
//		cout<<vis[i]<<" "; 
	}
//	cout<<endl;
	for(int i=1;i<=q;i++){
		memset(num,0,sizeof num);
		for(int j=l[i];j<=r[i];j++){
			vis[j]--;
		}
		int tot=0;
		for(int j=1;j<=n;j++){
			if(vis[j])
				tot++;
			if(vis[j]==1)
				book[j]=1;
			else
				book[j]=0;
			num[j]=num[j-1]+book[j];
		}
//		cout<<tot<<endl;
//		for(int j=1;j<=n;j++)
//			cout<<num[j]<<" ";
//		cout<<endl;
		for(int j=1;j<=q;j++){
			if(i==j)
				continue;
//			cout<<"第"<<j<<" : "<<tot-(num[r[j]]-num[l[j]-1])<<endl; 
			res=max(res,tot-(num[r[j]]-num[l[j]-1]));
		}
		for(int j=l[i];j<=r[i];j++)
			vis[j]++;
	}
	cout<<res<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值