POJ2442 堆

来源:互联网 发布:什么电话卡最划算知乎 编辑:程序博客网 时间:2024/06/16 07:02

2017年3月19日 | ljfcnyali
题目大意
m行n列的一个数矩阵,每行抽一个数,可以同列,那么有n^m种sequence组合,在这些sequence中,找出:sequence和最小的n个sequence组合。

Sample Input

12 31 2 32 2 3123412 31 2 32 2 3

Sample Output

3 3 413 3 4

题目分析
当行数大于等于2行时候,先比较第一行和第二行的和,把较小的放在第一行,把第一行压入优先队列
行数只有1行的时候,不进行该操作,直接把第一行的数压入优先队列(否则会造成第二行是0行和第一行交换后,把0行压入优先队列,wa掉)
对接下来的第2行到第m行
先把优先队列输入到一个数组a里面,并把优先队列清空,a是从大到小的,那么接下来的遍历都是倒序遍历
排序该行,然后该行第一个数和a中所有数相加压入优先队列
对该行的第二个到第n个数每个数,和a里面每个数相加,如果比优先队列最大的元素小,那么弹出最大元素,压入该元素,比最大元素大,则break,跳到该行的下一个数

AC代码

/*************************************************************************    > File Name: POJ2442.cpp    > Author: ljf-cnyali    > Mail: ljfcnyali@gmail.com     > Created Time: 2017-03-19 10:49:34 ************************************************************************/#include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<algorithm>#include<map>#include<set>#include<vector>#include<queue>using namespace std;#define REP(i, a, b) for(int i = (a), _end_ = (b);i <= _end_; ++ i)#define mem(a) memset((a), 0, sizeof(a))#define str(a) strlen(a)const int maxn = 10000;priority_queue <int> Q;int num[2000][maxn];int a[maxn];int n, m;int main() {#ifndef ONLINE_JUDGE    freopen("input.txt", "r", stdin);    freopen("output.txt", "w", stdout);#endif    int T;    scanf("%d", &T);    while(T --) {        scanf("%d%d", &m, &n);        REP(i, 1, m)            REP(j, 1, n)                scanf("%d", &num[i][j]);        if(m >= 2) {            int sum1 = 0, sum2 = 0;            REP(i, 1, n)                sum1 += num[1][i];            REP(i, 1, n)                sum2 += num[2][i];            if(sum2 > sum1)                swap(num[1], num[2]);        }        REP(i, 1, n)            Q.push(num[1][i]);        REP(i, 2, m) {            sort(num[i] + 1, num[i] + n + 1);            REP(j, 1, n) {                a[j] = Q.top();                Q.pop();            }            REP(j, 1, n)                Q.push(num[i][1] + a[j]);            REP(j, 2, n)                for(int k = n; k >= 1; -- k)                    if(num[i][j] + a[k] < Q.top()) {                        Q.pop();                        Q.push(num[i][j] + a[k]);                    }                    else                        break ;        }        REP(i, 1, n) {            a[i] = Q.top();            Q.pop();        }        for(int i = n; i >= 2; -- i)            printf("%d ", a[i]);        printf("%d\n", a[1]);    }    return 0;}

本文转自:http://ljf-cnyali.cn/index.php/archives/91