poj2442 堆

题意:给你n*m的矩阵,然后每行取一个元素,组成一个包含n个元素的序列,一共有n^m种序列,

让你求出序列和最小的前n个序列的序列和。

先介绍下堆的基本操作:

int arr[N];

make_heap(arr+1,arr+N);//对数组arr建堆,堆里第一个元素为最大值

pop_heap(arr+1,arr+N+1);//将第一个元素与最后一个元素交换

push_heap(arr+1,arr+N+1);//录入元素

sort_heap(arr+1,arr+N+1);//排序

思路:用普通方法超时,用堆做 具体如下:

1.将第一序列读入sum中,排序。

2.将数据读入num向量中排序。

用arr数组存sum[1] + num[i] ( 1<=i<=n)的和

用make_heap对arr建堆。

然后for循环比较sum[1] + num[i] (1<=i<=n)与堆arr的顶点,前者大则退出,否则删除

堆的顶点,插入前者。

3.将arr的数据拷贝到sum中,并对sum按升序排序

4.循环2,3步,直到所有数据读入完毕。

5.打印sum中的数据即为结果。

代码:

#include <iostream>

#include <cstdio>

#include <cmath>

#include <cstring>

#include <algorithm>

#include <vector>

#include <queue>

#include <stdlib.h>

#include <string.h>

#define N 3000

#define INF 10000000

#define eps 10E-9

#define mem(a)  memset(a,0,sizeof(a))

#define w(a)   while(a)

#define s(a)   scanf("%d",&a)

#define ss(a,b)   scanf("%d%d",&a,&b)

using namespace std;

int arr[N],num[N],sum[N];

int main()

{

int n,i,j,k,m,t;

s(t);

w(t--)

{

mem(sum);

ss(m,n);

for(i=1; i<=n; i++)

s(sum[i]);

for(i=2; i<=m; i++)

{

mem(num);

sort(sum+1,sum+n+1);

for(j=1; j<=n; j++)

{

s(num[j]);

}

sort(num+1, num+n+1);

for(j=1; j<=n; j++)

arr[j]=sum[1]+num[j];

make_heap(arr+1,arr+n+1);

for(j=2; j<=n; j++)

{

for(k=1; k<=n; k++)

{

int cnt=sum[j]+num[k];

if(cnt>=arr[1])

break;

pop_heap(arr+1,arr+n+1);

arr[n]=cnt;

push_heap(arr+1,arr+n+1);

}

}

for(j=1; j<=n; j++)

sum[j]=arr[j];

}

sort(sum+1,sum+n+1);

for(i=1; i<n; i++)

printf("%d ",sum[i]);

printf("%d\n",sum[i]);

}

return 0;

}

时间: 2024-11-05 15:55:12

poj2442 堆的相关文章

poj2442 堆应用

#include <cstdio> #include <cstring> #include <string> #include <vector> #include <queue> #include <algorithm> #include <iostream> using namespace std; int main() { int t; int n,m; int num1[2010]; int num2[2010];

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

POJ-2442 Sequence(手写堆优化)

Sequence Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 9131   Accepted: 3037 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

LeetCode Lect7 堆及其应用

概述 堆是一颗完全二叉树.分为大根堆(父节点>=所有的子节点)和小根堆(父节点<=所有的子节点). 插入.删除堆顶都是O(logN),查询最值是O(1). 完全二叉树(Complete Binary Tree) 若设二叉树的深度为h,除第 h 层外,其它各层 (1-h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树. 完全二叉树是由满二叉树而引出来的.对于深度为K的,有N个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对

JavaScript栈和堆内存,作用域

1.栈 stack"和"堆 heap": 简单的来讲,stack上分配的内存系统自动释放,heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里.stack一般是静态分配内存,heap上一般是动态分配内存. 2.基本类型和引用类型: 基本类型:存放在栈内存中的简单数据段.数据大小确定,内存空间大小可以分配. 引用类型:存放在堆内存中的对象,变量中实际保存的是一个指针,这个指针指向另一个位置.每个空间大小不一样,要根据情况开进行特定的分配. 详见<Javas

堆内存、栈内存分析图

堆内存保存的是真正的数据,简单说是对象的属性信息 栈内存保存的是对内存的地址,简单理解对象名称

JVM学习(2)——技术文章里常说的堆,栈,堆栈到底是什么,从os的角度总结--转载http://www.cnblogs.com/kubixuesheng/p/5202561.html

转载自---http://www.cnblogs.com/kubixuesheng/p/5202561.html 俗话说,自己写的代码,6个月后也是别人的代码--复习!复习!复习!涉及到的知识点总结如下: 堆栈是栈 JVM栈和本地方法栈划分 Java中的堆,栈和c/c++中的堆,栈 数据结构层面的堆,栈 os层面的堆,栈 JVM的堆,栈和os如何对应 为啥方法的调用需要栈 属于月经问题了,正好碰上有人问我这类比较基础的知识,无奈我自觉回答不是有效果,现在深入浅出的总结下: 前一篇文章总结了:JV

数据结构中的堆

一:堆排序      堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种.可以利用数组的特点快速定位指定索引的元素.堆分为大根堆和小根堆,是完全二叉树.大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i].在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶.下面附上简单C#简单实现: using System; using System.Collections.Generi

堆和栈 的区别

栈:自动回收 堆:1.内存地址  2.初始化默认值 3.垃圾回收机制 int a  = 5;  在栈中. int[] b =null;  此时null 代表 不指向任何堆. int [] c =new int[5];在堆中开辟一块空间.此时 c指一块内存地址. =======================学习黑马java视频学习的,讲的很生动,又缕了一遍.一会该练吉他了 ====以下为网上找的资料 1.在看例子之前,确保你理解以下几个术语: 栈:由JVM分配区域,用于保存线程执行的动作和数据引