• POJ 2442 Sequence(堆的应用)


    Sequence

    Time Limit: 6000MS

     

    Memory Limit: 65536K

    Total Submissions: 4906

     

    Accepted: 1490

    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

     解题报告:这道题的题意是给我们m, n,下面有m行,每行有n个数,让我们求出前n个最小组合的和,共有n ^ m种的组合,但是只是让我们求出前n组即可,思路就是利用堆的性质,在遍历求和的同时调整堆;用的是STL写的

    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAX = 2010;
    int a[MAX], b[MAX], heap[MAX];
    int main()
    {
        int i, j, m, n, t, flag;
        scanf("%d", &t);
        while (t --)
        {
            scanf("%d%d", &m, &n);
            for (i = 0; i < n; ++i)
            {
                scanf("%d", &a[i]);
            }
            sort(a, a + n);//将数组a按从小到大排序
            while (-- m)
            {
                for (i = 0; i < n; ++i)
                {
                    scanf("%d", &b[i]);
                }
                sort(b, b + n);//将数组b按从小到大排序
                for (i = 0; i < n; ++i)
                {
                    heap[i] = a[i] + b[0];
                }
                make_heap(heap, heap + n);//make_heap 是按照给定的排序准则,把“最大”的元素排列到首位,而其他元素看上去并非有序:
                //相当于建立大顶堆
                // 例如:输入 5个数 2 4 6 5 3 经历操作是 6 5 4 2 3
                for (i = 1; i < n; ++i)
                {
                    flag = 0;
                    for (j = 0; j < n; ++j)
                    {
                        int temp = b[i] + a[j];
                        if (temp < heap[0])
                        {
                            //pop_heap()不是真的把最大(最小)的元素从堆中弹出来。而是重新排序堆
                            //它把0和i个元素交换,然后将[0,i)的数据再做成一个大顶堆堆。
                            pop_heap(heap, heap + n);
                            heap[n - 1] = temp;
                            //push_heap()假设由[0,i)是一个有效的堆,
                            //然后,再把堆中的新元素加进来,做成一个堆。
                            push_heap(heap, heap + n);
                            flag = 1;
                        }
                        else
                        {
                            break;//当前已经是最小了
                        }
                    }
                    if (flag == 0)
                    {
                        break;//已经求出前n个最小的组合的和了
                    }
                }
                for (i = 0; i< n; ++i)
                {
                    a[i] = heap[i];
                }
                sort(a, a + n);//重新排序
            }
            for (i = 0; i < n - 1; ++i)
            {
                printf("%d ", a[i]);
            }
            printf("%d\n", a[n - 1]);
        }
        return 0;
    }
  • 相关阅读:
    go相关
    mac下使用vscode技巧
    mac下secureCRT的使用技巧
    python subprocess实时输出
    python中多级目录导入模块问题
    python的print与sys.stdout
    python中类相关笔记
    python中sys.stdout.flush()的作用
    nginx+uwsgi配置
    虚拟机的 基本配置
  • 原文地址:https://www.cnblogs.com/lidaojian/p/2441311.html
Copyright © 2020-2023  润新知