YbtOJ 数据结构课堂过关 例2 序列合并【大根堆】※

在这里插入图片描述


思路

这道题我们可以从题目中得到一个简单的规律:
a 1 + b 1 < a 1 + b 2 < a 1 + b 3 a1+b1<a1+b2<a1+b3 a1+b1<a1+b2<a1+b3
a 2 + b 1 < a 2 + b 2 < a 2 + b 3 a2+b1<a2+b2<a2+b3 a2+b1<a2+b2<a2+b3
a 3 + b 1 < a 3 + b 2 < a 3 + b 3 a3+b1<a3+b2<a3+b3 a3+b1<a3+b2<a3+b3
我们可以从第一列中找一个最小的和,记录答案。
然后从答案的位置往后推一个和,再与前面的答案进行比较。
用样例来举例,顺序就是:
max ⁡ ( a 1 + b 1 , a 2 + b 1 , a 3 + b 1 ) → 3 \max(a1+b1,a2+b1,a3+b1)\to 3 max(a1+b1,a2+b1,a3+b1)3
max ⁡ ( a 1 + b 2 , a 2 + b 1 , a 3 + b 1 ) → 6 \max(a1+b2,a2+b1,a3+b1)\to 6 max(a1+b2,a2+b1,a3+b1)6
max ⁡ ( a 1 + b 3 , a 2 + b 1 , a 3 + b 1 ) → 7 \max(a1+b3,a2+b1,a3+b1)\to 7 max(a1+b3,a2+b1,a3+b1)7
其实就是一个贪心。

代码

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int n,a[100010],b[100010];
priority_queue<pair<int,pair<int,int> > > q;
int main()
{
	cin>>n;
	for(int i=1; i<=n; i++)
	   scanf("%d",&a[i]);
	for(int i=1; i<=n; i++)
	   scanf("%d",&b[i]);
	for(int i=1; i<=n; i++)
	   q.push(make_pair(-a[i]-b[1],make_pair(i,1)));
	for(int i=1; i<=n; i++)
	 {
	 	int x=q.top().second.first,y=q.top().second.second;
	 	q.pop();
	 	cout<<a[x]+b[y]<<" ";
	 	q.push(make_pair(-a[x]-b[y+1],make_pair(x,y+1)));
	 }
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值