zoukankan      html  css  js  c++  java
  • POJ-2442-Sequence(二叉堆)

    POJ-2442

    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就不能更新。
    1. i=1,j=1
      • 更新i=2,j=1, flag = true
      • 更新i=1, j=2, flag = false
    2. 假如选中i=2,j=1,flag = true
      • 由于是true,可以更新i=3,j=1,flag = true
      • 更新i=2,j=2,flag = false
    3. 假如选中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;
    }
    
    注:转载请注明出处
  • 相关阅读:
    Login
    2Sum,3Sum,4Sum,kSum,3Sum Closest系列
    Word Search II
    Word Search
    Linux命令四
    linux命令三
    Linux命令二
    Linux命令一
    网络基础
    操作系统
  • 原文地址:https://www.cnblogs.com/1625--H/p/9475528.html
Copyright © 2011-2022 走看看