POJ-2442-Sequence(二叉堆)
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
题意:给M个数量为N的序列,从每个序列中任取一个数求和,可以构成N^M个和,求其中最小的N个和。
分析:
- 两组两组的看,首先要排序,然后从头开始找最小的N个和。
- 怎么找是个问题,对于第一组我们取i=1,第二组取j=1,然后a[1]+b[1]肯定是最小的,然后a[2]+b[1],a[1]+b[2]进入候选项,如果我们下一次选中了a[2]+b[1],那么我们又要将a[3]+b[1],a[2]+b[2]加入候选项。
- 但是我们要保证产生候选项不能重复,比如a[1]+b[2]和a[2]+b[1]都可以产生a[2]+b[2],所以我们要排除其中的一种,也就是说,我们要将候选项的下标计算变得有限制。
- 候选项的下标都是通过选中当前项的下标加一得到的,那么为了避免重复,我们要制定一种规则。假如规定为如果j+1,那么这个候选项被选中的时候i就不能更新。
- i=1,j=1
- 更新i=2,j=1, flag = true
- 更新i=1, j=2, flag = false
- 假如选中i=2,j=1,flag = true
- 由于是true,可以更新i=3,j=1,flag = true
- 更新i=2,j=2,flag = false
- 假如选中i=1,j=2,flag = false
- 由于false,不能更新i
- 更新i=1,j=3,flag = false
......
#define MAX 2001
#define MAXM 101
int n,m;
int a[MAXM][MAX];
struct node
{
int i,j;
int val;
bool model;
bool operator<(const node&a)const
{
return val>a.val;
}
};
int main()
{
int T;
cin>>T;
for(int r=0;r<T;r++)
{
cin>>m>>n;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
scanf("%d",&a[i][j]);
sort(a[i],a[i]+n);
}
int tmp[MAX];
node temp;
memcpy(tmp,a[0],sizeof(int)*n);
for(int k=1;k<m;k++)
{
int i=0,j=0,c=0,val = tmp[0]+a[k][0];
bool flag = 1;
priority_queue<node> q;
while(c<n)
{
a[0][c++] =val;
if(flag)
{
temp.i = i+1,temp.j = j,temp.val = tmp[i+1]+a[k][j],temp.model = true;
q.push(temp);
}
temp.i = i,temp.j = j+1,temp.val = tmp[i]+a[k][j+1],temp.model = false;
q.push(temp);
i = q.top().i,j = q.top().j,val = q.top().val,flag = q.top().model;
q.pop();
}
for(int i=0;i<n;i++)
{
tmp[i] = a[0][i];
}
}
printf("%d",tmp[0]);
for(int i=1;i<n;i++)
printf(" %d",tmp[i]);
puts("");
}
return 0;
}