cunzai_zsy0531

关注我

CF1400E Clear the Multiset 题解

考虑一个分治:每次如果要用第一种,一定是给整个区间用,直到没有办法覆盖整个区间,用的次数是 \(\min_{i=L}^R a_i\) 次,减去它之后分别递归最小值的两边。注意到如果某一次不使用第一个操作,那么以后也都不会用了,此时操作总数就是不为 \(0\) 的位置个数。复杂度最慢也是 \(O(n^2)\) 的。

点击查看代码
const int N=5000+13;
int a[N],n;
int solve(int l,int r){
	if(l>r) return 0;
	if(l==r) return a[l]>0;
	int cnt=0;
	for(int i=l;i<=r;++i) cnt+=(a[i]>0);
	int p=l;
	for(int i=l+1;i<=r;++i)
		if(a[i]<a[p]) p=i;
	int tmp=a[p];
	for(int i=l;i<=r;++i) a[i]-=tmp;
	std::vector<int> b;
	for(int i=l;i<=r;++i) b.pb(a[i]);
	int res1=solve(l,p-1);
	for(int i=l;i<=r;++i) a[i]=b[i-l];
	int res=min(cnt,res1+solve(p+1,r)+tmp);
	return res;
}
int main(){
	read(n);
	for(int i=1;i<=n;++i) read(a[i]);
	print(solve(1,n));
	return 0;
}
posted @ 2022-05-28 15:20  cunzai_zsy0531  阅读(30)  评论(0编辑  收藏  举报