【POJ2442】Sequence 解題報告+代碼

 
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
//#define INPUT
using namespace std;
/**
    Problem:POJ2442 - Sequence
    Begin Time : 2nd/March/2012 1:00 p.m.
    End Time: 2nd/March/2012 4:14 p.m
    Cost Time: 3H 14Min
    看的別人的解題報告過的,非常感謝
    http://hi.baidu.com/%C0%B6%C9%ABarch/blog/item/f9d343f49cd92e53d7887d73.html
    的博主!
    思路:
    我們要找到n個smallest的數,用貪心法可以解決這一問題。
    (1)維護兩個數組,a和b,以及一個大根堆p
        循環不變式:
        (1)初始化
            將元素讀入a,將a排序(從小到大)
            執行並重復(2)
        (2)保持
            對於這全部數據第二行到第m行(從第二行開始,因爲第一行讀到a裏了)
            將元素讀入b,將b排序(從小到大)
            For i = 0 to n -1
                heap.push(a[i]+b[0]);
            然後
            for(int i = 1; i < n;i++)
            {
                for(int j = 0 ; j < n; j++)
                {
                    if( (b[i] + a[j]) > heap.top() ) break;
                    heap.pop(); ///從heap中刪除一個最大的元素,從而保證heap中元素數目不變
                    heap.push(b[i] + a[j]);
                }
            }
            /////這樣,就選出了n個最小值
            然後把heap中的n個值按照從小到大給
            a[1] -> a[n],並將heap清空。
            執行(2)
        (3)最終結果
            輸出a中全部元素就可以了,注意,對於每個case都要換行哦!
*/
bool comp(int a,int b)
{
    return b > a;
}
int main(int argc,char* argv[])
{
#ifdef INPUT
    freopen("b:\\acm\\poj2442\\input.txt","r",stdin);
#endif
    int T;
    scanf("%d",&T);
    for(int i = 0 ; i < T; i++)
    {
        int m = 0 , n = 0;
        vector<int> a;vector<int> b;
        priority_queue<int> h_heap;
        a.clear();b.clear();

        int buf = 0;
        scanf("%d%d",&m,&n);
        for(int j = 0 ; j < n; j++)
        {
            scanf("%d",&buf);
            a.push_back(buf);
        }
        sort(&a[0],&a[0]+n,comp);
    for(int z = 0 ; z < m - 1; z++)
    {
        b.clear();
       for(int j = 0 ; j < n; j++)
        {
            scanf("%d",&buf);
            b.push_back(buf);
        }
        sort(&b[0],&b[0]+n,comp);
        for(int j = 0; j < n; j++)
        {
            h_heap.push(a[j]+b[0]);
        }
        ///這時候b已經選過了;
        for(int j = 1; j < n; j++)
        {
            for(int k = 0 ; k < n ; k++)
            {
                if ( b[j] + a[k] > h_heap.top() )
                {
                    break;
                }
                else
                {
                    h_heap.pop();
                    h_heap.push(b[j]+a[k]);
                }
            }
        }
        //////這時候已經選出來該兩行的n個最小值了
        for(int j = 0; j < n; j++)
        {
            a[ n - 1 - j ] = h_heap.top();
            h_heap.pop();
        }
        //////copy回去,把a
    }
        for(int j = 0 ; j < n; j++)
        {
            printf("%d ",a[j]);
        }
        printf("\n");
    }
    return 0;
}

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章