P1631 序列合并

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;
}
原文地址:https://www.cnblogs.com/Lance1ot/p/8761817.html