Sequence

題目連接:http://dsalgo.openjudge.cn/binarytree/12/html

總時間限制: 3000ms 內存限制: 65536kB
描述

給定m個數字序列,每一個序列包含n個非負整數。咱們從每個序列中選取一個數字組成一個新的序列,顯然一共能夠構造出n^m個新序列。接下來咱們對每個新的序列中的數字進行求和,一共會獲得n^m個和,請找出最小的n個和ios

輸入
輸入的第一行是一個整數T,表示測試用例的數量,接下來是T個測試用例的輸入
每一個測試用例輸入的第一行是兩個正整數m(0 < m <= 100)和n(0 < n <= 2000),而後有m行,每行有n個數,數字之間用空格分開,表示這m個序列
序列中的數字不會大於10000
輸出
對每組測試用例,輸出一行用空格隔開的數,表示最小的n個和
樣例輸入
1
2 3
1 2 3
2 2 3
樣例輸出
3 3 4

分析:ide

這個題用優先隊列來處理。維護一個長度爲n的優先隊列,每次輸入後都對前n個最小和進行更新,m-1次迭代後獲得最終的前n個最小和。函數

優先隊列內部是用堆來實現的,如果水平高的童鞋能夠本身實現堆去試一下。測試

下面直接使用C++ STL的優先隊列來完成工做。spa

關於優先隊列能夠參考:http://www.javashuo.com/article/p-qinhaodg-ky.html.net

關於sort排序函數參考:http://www.javashuo.com/article/p-beuozbxx-gg.htmlcode

AC代碼以下:htm

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <queue>
 5 #include <algorithm>
 6 using namespace std;
 7  
 8 const int maxn = 2005;
 9 int t,m,n,a[maxn],b[maxn];
10 priority_queue<int> q;//利用a維護前n個最小和
11  
12 int main()
13 {
14     scanf("%d",&t);
15     while(t--) {
16         scanf("%d%d",&m,&n);
17         for (int i = 0; i < n; ++i) scanf("%d",&a[i]);sort(a,a+n);    //a存儲前n個最小和
18         m--;
19         while(m--) {
20             for (int i = 0; i < n; ++i) scanf("%d",&b[i]);sort(b,b+n);
21             for (int i = 0; i < n; i++) q.push(a[i]+b[0]);    //生成長度爲n的優先隊列
22             for (int i = 1; i < n; ++i)    {    //計算剩餘的組合,並更新隊列
23                 int j;
24                 for (j = 0; j < n; ++j)
25                     if(b[i]+a[j]<q.top()) q.pop(),q.push(b[i]+a[j]);//a剪枝
26                     else break;
27                 if(j == 0) break;//b剪枝,b[i]+a[0]都不行,那b[i+1]+a[0]或b[i]+a[1]也不行
28             }    
29             for (int i = n-1; i >= 0; i--) a[i] = q.top(),q.pop();    //爲下次更新做準備
30         }
31         for (int i = 0; i < n; i++) printf("%d%c",a[i],i == n-1?'\n':' ');
32     }
33     return 0;
34 }
View Code

代碼來自csdn:https://blog.csdn.net/xxiaobaib/article/details/78907588blog

相關文章
相關標籤/搜索