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的一个矩阵,然后每次选择一个最优的,并把它后面的提到前面来判断更优
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;
}
作者:qbning
-------------------------------------------
个性签名:曾经的我们空有一颗望海的心,却从没为前往大海做过真正的努力
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!