P1631 序列合并[优先队列]

P1631 序列合并

这个没做出来属实有些惭愧。看了题解觉得很妙。如果直接想的话可能反而很麻烦

题目是给两个n个数的不下降序列,问这两个序列任意各取出一个后相加的最小的n个数是什么。

直接贴题解吧题解 P1631 【序列合并】

一共会产生n*n个数,

a[1]+b[1]<=a[1]+b[2]........<=a[1]+b[n]

a[2]+b[1]<=a[2]+b[2]........<=a[2]+b[n]

.

.

a[n]+b[1]<=a[n]+b[2]........<=a[n]+b[n]

先把这前n个第一个数放入优先队列,最小的加入答案然后把它的下一个放入优先队列即可

下面这个题也是一个套路

答案可以表示成n*m的一个矩阵,然后每次选择一个最优的,并把它后面的提到前面来判断更优

P2085 最小函数值 

P1631 序列合并
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
ll n,a[100005],b[100005],q[100005];
priority_queue<pair<int,int>, vector<pair<int,int> >,greater<pair<int, int> > >cc;
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int j=1;j<=n;j++)
	{
		cin>>b[j];
		q[j]++;
		cc.push(pair<int,int>(a[1]+b[j],j));
	}
	while(n--)
	{
		auto cx=cc.top();
		cc.pop();
		cout<<cx.first<<' ';
		cc.push(pair<int,int>(b[cx.second]+a[++q[cx.second]],cx.second));
	}
	return 0;
}
最小函数值
 #include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
struct num
{
	int a,b,c,id,val;
	bool operator<(num y)const
	{
		return val>y.val;
	}
};
int aa[10005];
priority_queue<num>cc;
signed main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		num tmp;
		tmp.id=i;
		cin>>tmp.a>>tmp.b>>tmp.c;
		tmp.val=tmp.a+tmp.b+tmp.c;
		aa[i]=1;
		cc.push(tmp);
	}
	while(m--)
	{
		num tmp=cc.top();
		cc.pop();
		cout<<tmp.val<<' ';
		++aa[tmp.id];
		tmp.val=tmp.a*(aa[tmp.id]*aa[tmp.id])+tmp.b*(aa[tmp.id])+tmp.c;
		cc.push(tmp);
	}
	return 0;
}
posted @ 2023-08-11 20:12  qbning  阅读(21)  评论(0编辑  收藏  举报
描述