《算法竞赛进阶指南》0x17二叉堆 POJ2442 矩阵取数求前N大

Posted randy-lo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法竞赛进阶指南》0x17二叉堆 POJ2442 矩阵取数求前N大相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=2442

给定一个M*N的矩阵,要求从每一行中都取出一个数然后累加,问最小的N个累积和为多少。使用堆可以在O(MNlogN)时间复杂度内求出。

M行的最大取法一定是通过前M-1行的最大取法+第M行取数然后求前N大获取的,所以有归纳法可以考虑两组数据进行选择。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define maxn 2004
typedef pair<int,int> P;

int a[maxn],b[maxn],c[maxn];
int n,m;
void merge(){//将ab中最小的N对数的和存入a中 
    priority_queue<P,vector<P>,greater<P> > heap;//保存值以及a数组中的下标 
    for(int i=0;i<n;i++)heap.push(make_pair(b[i]+a[0],0));
    for(int i=0;i<n;i++){
        P t=heap.top();
        heap.pop();
        int s=t.first,p=t.second;
        c[i]=s;
        heap.push(make_pair(s-a[p]+a[p+1],p+1));
    }
    for(int i=0;i<n;i++)a[i]=c[i];
}
int main(){
    int T;
    cin>>T;
    while(T--){
        scanf("%d%d",&m,&n);
        for(int i=0;i<n;i++)scanf("%d",&a[i]);
        sort(a,a+n);
        for(int i=0;i<m-1;i++){
            for(int j=0;j<n;j++)scanf("%d",&b[j]);
            merge();
        }
        for(int i=0;i<n;i++)printf("%d ",a[i]);
        puts("");
    }
}

 

以上是关于《算法竞赛进阶指南》0x17二叉堆 POJ2442 矩阵取数求前N大的主要内容,如果未能解决你的问题,请参考以下文章

《算法竞赛进阶指南》0x43线段树 扫描线算法 POJ2482

《算法竞赛进阶指南》0x27A* 八数码问题 POJ1077

《算法竞赛进阶指南》0x15 POJ1961 KMPNext数组求循环节

算法竞赛进阶指南扩展最大子段和POJ1050ToTheMax

《算法竞赛进阶指南》0x25广度优先搜索 POJ3322 Bloxorz I

《算法竞赛进阶指南》0x11栈 单调栈求矩形面积 POJ2559