abc345 E 求调
  • 板块学术版
  • 楼主sky_0x006
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/3/16 23:44
  • 上次更新2024/3/17 09:40:46
查看原帖
abc345 E 求调
825958
sky_0x006楼主2024/3/16 23:44

大体思路如下

找出所有连续相同颜色区间,将每个区间的最大留下,称为第一轮筛选,如果第一轮删掉的个数超过上限,说明无解。

若第一轮删掉的不足以达到上限,则进行第二轮筛选,在不会生成新的连续区间的情况下尽可能删除小权重的球

代码如下

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n, k;//如题
ll a[1000015], b[1000015];//a颜色编号、b权重
ll c[1000015], d[1000015];//c连续颜色区间左端点,d右端点
ll m[1000015];//每个连续颜色区间权重的最大值
ll co[1000015];//每个连续颜色区间的颜色编号 
ll cnt;//连续颜色区间数量 ,同时易得其为第二轮筛选时球的个数
struct sss {
	ll vol, to;//vol权重,to指针指向aaa[]
} aa[1000015];//第二轮筛选的数组
bool cmp(sss a, sss b) {
	return a.vol<b.vol;
}
ll aaa[1000015];//记忆数组 ,存储颜色编号与排序
ll answer;//答案 
ll asdf;//表示第二轮筛选了几个 
int main() {
	cin>>n>>k;
	for(ll i=1; i<=n; i++)	{
		cin>>a[i]>>b[i];
		if(a[i]==a[i-1]) {
			d[cnt]=i;
			m[cnt]=max(m[cnt],b[i]);//找每个区间的最大权重球 
		} else {
			cnt++;
			c[cnt]=d[cnt]=i;
			m[cnt]=b[i];
			co[cnt]=a[i]; 
		}
	}
//	cout<<"cnt: "<<cnt<<'\n';
	if(n-cnt>k) {
		cout<<"-1";
		return 0;
	} else {
		for(ll i=1; i<=cnt; i++) {//只留下每个连续区间最大的,其他的不管 
			aa[i].vol=m[i];
			aa[i].to=i;
			aaa[i]=co[i];
			answer+=m[i];
//			cout<<"sdf "<<co[i]<<" "<<m[i]<<'\n';
		} 
		sort(aa+1, aa+cnt+1, cmp);//按权重排序 
//		for(ll i=1; i<=cnt; i++) cout<<aa[i].vol<<" "<<aa[i].to<<'\n';
//		cout<<"sdfsdfsd "<<asdf<<" "<<k-(n-cnt)<<'\n';
		for(ll i=1; i<=cnt; i++) {
//			cout<<"i: "<<i<<" "<<aa[i].to-1<<" "<<aa[i].to+1<<" "<<aaa[aa[i].to-1]<<" "<<aaa[aa[i].to+1]<<'\n';
			if(asdf==k-(n-cnt)) break;//删除到上限 
			if(aaa[aa[i].to-1]!=aaa[aa[i].to+1]) answer-=aa[i].vol, asdf++;//在删除后不会出现连续颜色区间的情况下删除权重尽可能小的球 
		}
//		cout<<"sdfsdfsd s "<<asdf<<" "<<k-(n-cnt)<<'\n';
		if(asdf!=k-(n-cnt)) cout<<"-1";//如果删不到上限,就-1 
		else cout<<answer;//输出答案 
	}
	return 0;
}
2024/3/16 23:44
加载中...