题目链接
序列合并
最小函数值
题解
这两道题做法基本一样,是使用同一种套路解决的,这里用序列合并来举例说明。
序列合并要求出N2N2个和中最小的N个数。
我们用一个堆来维护我们需要的数,并且保证当前最小值一定在堆中。
把a和b排个序。
这个堆首先要加入的就是(a[1]+b[i]),1≤i≤n(a[1]+b[i]),1≤i≤n这n个数字。
这表示与b[i]b[i]所有与a[x]a[x]组合的最小值。
我们从堆中取出一个最小的并打印输出之后,再把这个b[i]b[i]与下一个a,组合形成新的数值,并把它推入堆中。
一直取出n个元素即可。
代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef pair<int,int> pii;
const int maxn = 1e5+7;
int a[maxn],b[maxn],mark[maxn];
int main(){priority_queue<pii,vector<pii>,greater<pii> >Q;int N;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){mark[i] = 1;Q.push(make_pair(a[1]+b[i],i));}while(N--){pii p = Q.top();Q.pop();printf("%d ",p.first);p.first = b[p.second] + a[++mark[p.second]];Q.push(p);}
}