P1631 序列合并
Posted $mathcal{Lance1ot}$
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1631 序列合并相关的知识,希望对你有一定的参考价值。
首先,对于最暴力的算法。就是将n^2个和全都枚举出来。然后排序
可是,在数据范围很大的时候,空间和时间都不能通过
所以我们就要优化~~ 废话~~
首先我们的贪心策略不会变。优化的只能是枚举和的步骤
我们来看,对于A中的第i项和B中的第j项(A、B都是升序)
只有第i项和第j-1项被取了之后,我们才有可能取到第i项和第j项
所以我们就可以将计算第i项和第j项的和推迟在第i项和第j-1项之后。就可以节省空间。
然后用栈进行维护
写程序的时候。我们要进行定序处理。
嗯,差不多就这么多了。
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int val1,val2;
int sum;
bool operator > (const node &b)
{
return sum>b.sum;
}//重载运算符
};
struct heap//堆模板
{
int tail;
node data[500000];
node top()
{
return data[1];
}
void swap(int a,int b)
{
node pass=data[a];
data[a]=data[b];
data[b]=pass;
}
void insert(node value)
{
data[++tail]=value;
int pos=tail;
while(pos&&data[pos>>1]>data[pos])
{
swap(pos>>1,pos);
pos>>=1;
}
return ;
}
void del()
{
swap(1,tail);
tail--;
int pos=1,pass;
while(pos<=tail)
{
pass=pos;
if(data[pass]>data[pos<<1]&&(pos<<1)<=tail)
pass=pos<<1;
if(data[pass]>data[pos<<1|1]&&(pos<<1|1)<=tail)
pass=pos<<1|1;
if(pass==pos)
break;
swap(pass,pos);
pos=pass;
}
return ;
}
};
int dat1[500000];
int dat2[500000];
heap h;
bool compare(const int &a,const int &b)
{
return a<b;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&dat1[i]);
for(int i=1;i<=n;i++)
scanf("%d",&dat2[i]);
sort(dat1+1,dat1+1+n,compare);
sort(dat2+1,dat2+1+n,compare);
node ha;
for(int i=1;i<=n;i++)
{
ha.sum=dat1[i]+dat2[1];
ha.val1=i;
ha.val2=1;
h.insert(ha);
}
int get=0;
while(get<n)
{
ha=h.top();
h.del();
printf("%d ",ha.sum);
ha.sum=dat1[ha.val1]+dat2[ha.val2+1];
ha.val2+=1;
h.insert(ha);
get+=1;
}
return 0;
}
以上是关于P1631 序列合并的主要内容,如果未能解决你的问题,请参考以下文章