区间合并+并查集

前言:写完这个题目的时候没意识到这个和区间合并是等价的,现在看起来确实是一个区间合并的题目

(注意这个多米诺骨牌是可以连续推倒的)


cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

#define int long long
int t;
int n,m;
const int N = (int)2e5+5;
struct node{
	int h,pos;
	bool operator<(node b){
		return pos < b.pos;
	}
}sto[N];
int fa[N];
int find(int x){
	if(x==fa[x]) return x;
	return fa[x] = find(fa[x]);
}
int ans[N];

bool cmp(int a,int b){
	return a>b;
}

signed main(){
	cin >> t;
	while(t--){
		cin >> n >> m;
		for(int i=1;i<=n;i++){
			cin >> sto[i].h;
		}
		for(int i=1;i<=n;i++){
			cin >> sto[i].pos;
		}
		sort(sto+1,sto+1+n);
		for(int i=1;i<=n;i++) fa[i] = i;
		int j;
		for(int i=1;i<=n;i=j){
			int hi = sto[i].h, posi= sto[i].pos;
			int en = hi + posi;
			for(j=i+1;j<=n;j++){
				int hj = sto[j].h, posj = sto[j].pos;
				if(en>=posj){  // 如果能够到达 
					fa[j] = i;
					//更新我们的长度
					en = max(en,hj+posj); 
				}else{
					break;
				}
			}
		}
		for(int i=1;i<=n;i++) ans[i] = 0;
		for(int i=1;i<=n;i++){
			int x = find(i);
			//cout << " i " << x << endl;
			ans[x]++;
		}

		sort(ans+1,ans+1+n,cmp);
		int e = 0;
		//cout << " ans 1 " << ans[1] << endl;
		for(int i=1;i<=m;i++){
			e+=ans[i];
		}
		cout << e << endl;
	}
	return 0;
}
相关推荐
珂朵莉MM26 分钟前
第七届全球校园人工智能算法精英大赛-算法巅峰赛产业命题赛第3赛季优化题--束搜索
人工智能·算法
Omics Pro1 小时前
首个!外源天然产物综合性代谢图谱
数据库·人工智能·算法·机器学习·r语言
JAVA社区1 小时前
Java高级全套教程(十)—— SpringCloudAlibaba超详细实战详解
java·开发语言·spring cloud·面试·职场和发展
弥树子1 小时前
踩坑记录:服务器内网调用接口,真实请求URL与官方公开URL不一致问题排查
开发语言·php
voidmort1 小时前
3. 微调(Fine-tuning)与强化学习(RL)的核心思想
python·深度学习·算法
z落落2 小时前
C# ToCharArray + foreach遍历 + String与StringBuilder
开发语言·c#
学代码的真由酱2 小时前
Java多用户一对一网页聊天室-测试报告
java·开发语言·功能测试·测试
人道领域2 小时前
【LeetCode刷题日记】669.修剪二叉搜索树
开发语言·python·算法
xiaoshuaishuai83 小时前
C# AvaloniaUI动态显示图片
开发语言·c#
QiLinkOS3 小时前
【从实验室到商业战场:发明专利如何重塑科技与企业的共生生态】
大数据·c语言·数据结构·c++·人工智能·单片机·算法