三、搜索和二分 [Cloned] D - 贪心

原题:

Given m sequences, each contains n non-negative integer. Now we may select one number from each sequence to form a sequence with m integers. It's clear that we may get n ^ m this kind of sequences. Then we can calculate the sum of numbers in each sequence, and get n ^ m values. What we need is the smallest n sums. Could you help us?

题意:

给m个数列,每个数列有n个数,从每个数列中取一个数,共有n**m种组合,我们要计算出所有组合的各自的加和,并求出前n小的加和

题解:

两个数列各个数字分别相加,取前n个小的存下,成为一个新的数列,而后再取一个新的数列,重复上述步骤。

代码:AC

#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int a[120][2010],b[2010];
priority_queue<int>p;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,m;
		cin>>n>>m;
		int i,j,k;
		for(i=0;i<n;i++)
		{
			for(j=0;j<m;j++)
				cin>>a[i][j];
			sort(a[i],a[i]+m);
		}
		for(i=0;i<m;i++)
			p.push(a[0][i]);
		for(i=1;i<n;i++)
		{
			for(j=0;j<m;j++)
			{
				b[j]=p.top();
				p.pop();
			}
			for(j=0;j<m;j++)
			{
				for(k=m-1;k>=0;k--)
				{
					if(j==0)
						p.push(a[i][j]+b[k]);
					else
					{
						if(a[i][j]+b[k]<p.top())
						{
							p.pop();
							p.push(a[i][j]+b[k]);
						}
						else
							break;
					}
				}
			}
		}
		for(j=0;j<m;j++)
		{
			b[j]=p.top();
			p.pop();
		}
		for(j=m-1;j>=0;j--)
		{
			if(j==0)
				cout<<b[j]<<endl;
			else
				cout<<b[j]<<" ";
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/npuyan/article/details/81414113