POJ2442——Squence(二叉堆+动态规划 | 滚动数组)

本文出自:http://blog.csdn.net/svitter

题意分析:

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^m组值。我们需要n组最小序列和。

输入输出分析:

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.

给T组测试样例。第一行包括两个整数m,n分别代表m个序列, n个整数。没有整数大于10000(没有超过int)

算法数据结构分析:

利用动态规划思想,分阶段解决问题。

使用两个数组作为滚动数组,利用c= 1-c进行切换。

a代表前k-1个序列的最小序列和的分布,b代表前k个序列最小阶段序列和。读入新的序列进行计算。

新读入的序列不停的更新b的阶段最小序列和,方法:用每一项与a中的每一个元素求和,计算出的b如果小于b数组的最大值,弹出最大值,将新计算出值加入b

假设数据为:

3 3

1 2 3

1 2 3

3 2 1

可得

2 3 4

3 4 5

4 5 6

取2 3 3

2 3 3

3 2 1

可得

5 6 6

4 5 5

3 4 4

取3 4 4

由此可见每次都是取都是取最佳的组合。

使用堆数据结构来获得每次的最大值。堆的实现包含在algorithm中(大顶堆)

AC代码:

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#include <algorithm>

using namespace std;

#define MAXN 2010

int m, n;
int t;

int a[2][MAXN];

int main()
{
    int i, j, k;
    int c;
    int temp1, temp2;
    freopen("test/test2", "r", stdin);
    scanf("%d", &t);

    while(t--)
    {
        scanf("%d%d", &m, &n);
        for(i = 0; i < n; i++)
            scanf("%d", &a[0][i]);
        make_heap(a[0], a[0]+n);
        c = 0;
        for(i = 1; i < m; i++, c = 1-c)
        {
            scanf("%d", &temp1);
            for(k = 0; k < n; k++)
                a[1-c][k] = a[c][k] + temp1;
            for(k = 1; k < n; k++)
            {
                scanf("%d", &temp1);
                for(j = 0; j < n; j++)
                {
                    temp2 = a[c][j] + temp1;
                    if(temp2 < a[1-c][0])
                    {
                        pop_heap(a[1-c], a[1-c]+n);
                        a[1-c][n-1] = temp2;
                        push_heap(a[1-c], a[1-c]+n);
                    }
                }
            }
        }
        sort(a[c], a[c]+n);
        for(i = 0; i < n-1; i++)
            printf("%d ", a[c][i]);
        printf("%d\n", a[c][n-1]);
    }
    return 0;
}

POJ2442——Squence(二叉堆+动态规划 | 滚动数组)

时间: 2025-01-04 23:42:47

POJ2442——Squence(二叉堆+动态规划 | 滚动数组)的相关文章

二叉堆(binary heap)

堆(heap) 亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因而实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权.堆即为解决此类问题设计的一种数据结构. 本文地址:http://www.cnblogs.com/archimedes/p/binary-heap.html,转载请注明源地址. 逻辑定义 n个

PHP利用二叉堆实现TopK-算法的方法详解

前言 在以往工作或者面试的时候常会碰到一个问题,如何实现海量TopN,就是在一个非常大的结果集里面快速找到最大的前10或前100个数,同时要保证 内存和速度的效率,我们可能第一个想法就是利用排序,然后截取前10或前100,而排序对于量不是特别大的时候没有任何问题,但只要量特别大是根本不可能 完成这个任务的,比如在一个数组或者文本文件里有几亿个数,这样是根本无法全部读入内存的,所以利用排序解决这个问题并不是最好的,所以我们这里就用 php去实现一个小顶堆来解决这个问题. 二叉堆 二叉堆是一种特殊的

二叉堆 及 大根堆的python实现

Python 二叉堆(binary heap) 二叉堆是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树.二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子树和右子树都是一个二叉堆. 当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆. 当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆. 二叉堆的存储 二叉堆一般用数组来表示.如果根节点在数组中的位置是1,第n个位置的子节点分别在2n和 2n+1.因此,第1个位置的子节点在2和3,第2

【qbxt!预习】二叉堆

qxbt的老师发消息来说让自己预习,本来想中考完之后认真学(颓)习(废)  没办法 0. 数据结构图文解析系列 1. 二叉堆的定义 二叉堆是一种特殊的堆,二叉堆是完全二叉树或近似完全二叉树.二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子树和右子树都是一个二叉堆.当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆. 当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆. 2. 二叉堆的存储 二叉堆一般使用数组来表示.请回忆一下二叉树的性质,

C++动态数组简单模拟二叉堆

//C++动态数组简单模拟二叉堆 #include<iostream> using namespace std; class BinaryHeap { private: int cap; //数组最大容量 int size; //当前元素个数 int* datas; //数组首地址 public: explicit BinaryHeap(int cap_) :cap(cap_), size(0) { datas = new int[cap]; } ~BinaryHeap(){ delete d

二叉堆的应用——查找长度为N数组中第M大数

看到这个题目首先想到是排序,那么时间复杂度自然就是O(NlgN).那么使用二叉堆如何解决呢? 对于下面一个数组,共有12个元素,我们的目标就是找出第5大元素——12 首先建立一个具有M个元素的最小堆,那么堆顶是这M个元素的最小值,接下来遍历剩下的元素,如果一个元素小于堆顶元素则不做任何操作,如果大于堆顶元素,则替换该元素,并且调整最小堆.显然最后堆的M个元素是最大的M个元素,而它们中最小的正式堆顶元素. 实现代码 Heap <Integer> h = new Heap<>(); I

算法—二叉堆

实现栈或是队列与实现优先队列的最大不同在于对性能的要求.对于栈和队列,我们的实现能够在常数时间内完成所有操作:而对于优先队列,插入元素和删除最大元素这两个操作之一在最坏情况下需要线性时间来完成.我们接下来要讨论的基于数据结构堆的实现能够保证这两种操作都能更快地执行. 1.堆的定义 数据结构二叉堆能够很好地实现优先队列的基本操作.在二叉堆的数组中,每个元素都要保证大于等于另两个特定位置的元素.相应地,这些位置的元素又至少要大于等于数组中的另两个元素,以此类推.如果我们将所有元素画成一棵二叉树,将每

堆排序:什么是堆?什么是最大堆?二叉堆是什么?堆排序算法是怎么样的?PHP如何实现堆排序?

本文标签:  堆排序 php php算法 堆排序算法 二叉堆 数据结构 REST   服务器 什么是堆 这里的堆(二叉堆),指得不是堆栈的那个堆,而是一种数据结构. 堆可以视为一棵完全的二叉树,完全二叉树的一个"优秀"的性质是,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素. 数组与堆之间的关系 二叉堆一般分为两种:最大堆和最小堆. 什么是最大堆 堆中每个父节点的元素值都大于等于其孩子结点(如果存在),这样的堆就是一个最大堆 因此,最大堆中的

在A*寻路中使用二叉堆

接上篇:A*寻路初探 GameDev.net 在A*寻路中使用二叉堆 作者:Patrick Lester(2003年4月11日更新) 译者:Panic 2005年3月28日 译者序:     这一篇文章,是"A* Pathfinding for Beginners.",也就是我翻译的另一篇文章<A*寻路初探>的补充,在这篇文章里,作者再一次展现了他阐述复杂话题的非凡能力,用通俗易懂的语句清晰的解释了容易让人迷惑的问题.还是那句话,如果你看了这篇文章仍然无法领会作者的意图,那