題目連接:http://dsalgo.openjudge.cn/binarytree/12/html
給定m個數字序列,每一個序列包含n個非負整數。咱們從每個序列中選取一個數字組成一個新的序列,顯然一共能夠構造出n^m個新序列。接下來咱們對每個新的序列中的數字進行求和,一共會獲得n^m個和,請找出最小的n個和ios
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 }
代碼來自csdn:https://blog.csdn.net/xxiaobaib/article/details/78907588blog