Sequence
| Time Limit: 6000MS | Memory Limit: 65536K | |
| Total Submissions: 12525 | Accepted: 4103 |
Description
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?
Input
The first line is an integer T, which shows the number of test cases, and then T test cases follow. The first line of each case contains two integers m, n (0 < m <= 100, 0 < n <= 2000). The following m lines indicate the m sequence respectively. No integer in the sequence is greater than 10000.
Output
For each test case, print a line with the smallest n sums in increasing order, which is separated by a space.
Sample Input
1 2 3 1 2 3 2 2 3
Sample Output
3 3 4
Source
POJ Monthly,Guang Lin
在洛谷的合并序列中得到启发,对于两个数组取前k小和问题,用to数组来记录arr【i】与tmp数组的第几个数相加,并用最小堆维护。
两个数组的理解后,多个的就很好办了,把前两个数组的前K小值放到轮换数组中,与后续数组进行相同的操作即可
//#include <bits/stdc++.h>
#include <iostream>
#include <queue>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 2e3+100;
const ll mod = 1e9+7;
//const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
//const ld e = exp(1);
ll T,n,m,arr[maxn],tmp[maxn],to[maxn]; //tmp轮换数组
int main()
{
//ios::sync_with_stdio(false);
//cin.tie(0),cout.tie(0);
cin >> T;
while(T--)
{
memset(arr,0,sizeof(arr));
memset(tmp,0,sizeof(tmp));
cin >> n >> m;
for(ll i = 1; i <= n; i++)
{
memset(to,0,sizeof(to));
priority_queue< pair<ll,ll> , vector < pair<ll,ll> >, greater< pair<ll,ll> > >Q;
for(ll j = 1; j <= m; j++)
{
if(i == 1)
cin >> tmp[j];
else
{
cin >> arr[j];
}
}
sort(tmp+1,tmp+1+m);
sort(arr+1,arr+1+m);
if(i >= 2)
{
for(ll j = 1; j <= m; j++)
{
to[j]=1; //arr数组第j个和tmp数组哪个相加
Q.push( make_pair( tmp[1]+arr[j],j ) );
}
ll ok[maxn];
for(ll k = 1; k <= m; k++)
{
ok[k] = Q.top().first;
ll t = Q.top().second;
Q.pop();
to[t]++;
Q.push( make_pair( tmp[ to[t] ]+arr[t],t ) );
}
for(ll k = 1; k <= m; k++)
{
tmp[k] = ok[k];
}
}
}
for(ll i = 1; i <= m; i++)
cout << tmp[i] << " ";
cout << endl;
}
return 0;
}
求最小序列和
本文介绍了一个算法问题,即从给定的多个整数序列中选取元素形成新的序列,目标是找到这些新序列中和最小的n个。文章通过使用轮换数组和最小堆的数据结构,提出了一种高效的解决方案。
903

被折叠的 条评论
为什么被折叠?



