Given m sequences, each contains n non-negative integer. Now we may select one number from each sequence to form a sequence with m integers. It's clear that we may get n ^ m this kind of sequences. Then we can calculate the sum of numbers in each sequence, and get n ^ m values. What we need is the smallest n sums. Could you help us?
Input
The first line is an integer T, which shows the number of test cases, and then T test cases follow. The first line of each case contains two integers m, n (0 < m <= 100, 0 < n <= 2000). The following m lines indicate the m sequence respectively. No integer in the sequence is greater than 10000.
Output
For each test case, print a line with the smallest n sums in increasing order, which is separated by a space.
Sample Input
1 2 3 1 2 3 2 2 3
Sample Output
3 3 4
思路:每次找出前两个序列的前n大,然后将这前n大当成新的序列与第三行处理,以此类推。取出堆顶元素的下标为(i, j)时,将(i, j + 1)与(i + 1, j)加入决策集。复杂度nmlogn.
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int T, m, n, a[105][2015], b[2015], c[2015], rec[2015]; 45 struct gg { 46 int i, j, k; 47 gg () {} 48 gg (int i, int j, int k) : i(i), j(j), k(k) {} 49 bool operator > (const gg &g) const { 50 if (a[i][j] + b[k] == a[g.i][g.j] + b[g.k]) { 51 return j + k > g.j + g.k; 52 } 53 return a[i][j] + b[k] > a[g.i][g.j] + b[g.k]; 54 } 55 }; 56 priority_queue<gg, vector<gg>, greater<gg> > que; 57 int main() { 58 scanf("%d", &T); 59 while (T--) { 60 scanf("%d%d", &m, &n); 61 for (int i = 1; i <= m; ++i) { 62 for (int j = 1; j <= n; ++j) { 63 scanf("%d", &a[i][j]); 64 } 65 sort(a[i] + 1, a[i] + n + 1); 66 } 67 for (int i = 1; i <= n; ++i) { 68 b[i] = a[1][i]; 69 } 70 for (int i = 2; i <= m; ++i) { 71 for (int j = 1; j <= n; ++j) { 72 rec[j] = 0; 73 } 74 while (que.size()) que.pop(); 75 que.push(gg(i, 1, 1)); 76 int index = 0; 77 while (que.size() && index < n) { 78 gg g = que.top(); que.pop(); 79 int jj = g.j, kk = g.k; 80 if (kk <= rec[jj]) continue; 81 else rec[jj] = kk; 82 if (jj < n) { 83 que.push(gg(i, jj + 1, kk)); 84 } 85 if (kk < n) { 86 que.push(gg(i, jj, kk + 1)); 87 } 88 c[++index] = a[i][jj] + b[kk]; 89 } 90 for (int j = 1; j <= n; ++j) { 91 b[j] = c[j]; 92 } 93 } 94 for (int i = 1; i < n; ++i) { 95 printf("%d ", b[i]); 96 } 97 printf("%d ", b[n]); 98 } 99 return 0; 100 }