UVa 11997 K Smallest Sums - 优先队列
2017-11-07 07:49
736 查看
题目大意 有k个长度为k的数组,从每个数组中选出1个数,再把这k个数进行求和,问在所有的这些和中,最小的前k个和。
考虑将前i个数组合并,保留前k个和。然后考虑将第(i + 1)个数组和它合并,保留前k个和。
如果暴力的话就进行就暴力枚举每一对,然后进行求和,然后再选出前k个,然而这样会TLE。
可以考虑将另外一个数组进行排序。然后可以看做是k个已经排好序的数组进行归并
{A[1] + B[1], A[1] + B[2], ...} {A[2] + B[1], A[2] + B[2], ...} {A[3] + B[1], A[3] + B[2], ...} . . . {A[k] + B[1], A[k] + B[2], ...}
对于每个数组,只有前一个值被取了,后一个值才有可能被取。
所以用一个优先队列进行维护,先将所有数组的第一个元素放进去,然后每次取出一个元素,再将它的后一个放入队列。
每次合并时间复杂度O(klogk),所以总时间复杂度为O(k2logk)
Code
/** * UVa * Problem#11997 * Accepted * Time: 190ms */ #include <bits/stdc++.h> using namespace std; typedef bool boolean; int k; int A[751], B[751], C[751]; int *X, *Y; typedef class Item { public: int x, b; Item(int x = 0, int b = 0):x(x), b(b) { } boolean operator < (Item xb) const { return X[x] + B[b] > X[xb.x] + B[xb.b]; } int getVal() { return X[x] + B[b]; } }Item; inline void merge() { priority_queue<Item> que; for(int i = 0; i < k; i++) que.push(Item(i, 0)); for(int i = 0; i < k; i++) { Item e = que.top(); que.pop(); Y[i] = e.getVal(); que.push(Item(e.x, e.b + 1)); } while(!que.empty()) que.pop(); swap(X, Y); } inline boolean init() { if(scanf("%d", &k) == EOF) return false; X = A, Y = C; for(int i = 0; i < k; i++) scanf("%d", X + i); sort(A, A + k); for(int i = 1; i < k; i++) { for(int j = 0; j < k; j++) scanf("%d", B + j); sort(B, B + k); merge(); } return true; } inline void solve() { for(int i = 0; i < k - 1; i++) printf("%d ", X[i]); printf("%d\n", X[k - 1]); } int main() { while(init()) { solve(); } return 0; }
相关文章推荐
- UVa - 11997 K Smallest Sums(优先队列多路归并)
- K Smallest Sums(Uva 11997) 多路归并+优先队列
- UVa 11997 K Smallest Sums (优先队列 & k路归并化为两两归并)
- 【优先队列之多路合并】UVA - 11997 K Smallest Sums
- UVa 11997 (优先队列 多路归并) K Smallest Sums
- uva11997 K Smallest Sums&&UVALive 3135 Argus(优先队列,多路归并)
- 优先队列 UVA 11997 K Smallest Sums
- uva 11997 K smallest sums (优先队列 多路归并)
- UVA 11997 K Smallest Sums 优先队列
- UVA11997_K_Smallest_Sums_多路并归_优先队列
- UVA-11997 - K Smallest Sums(优先队列)
- UVA 11997 - K Smallest Sums(多路归并)
- UVA11997 K Smallest Sums(并归,优先队列)
- UVa 11997 K Smallest Sums
- UVA 11997 K Smallest Sums(多路合并)
- UVA11997 - K Smallest Sums 优先队列,多路归并
- uva_11997,K Smallest Sums优先队列
- 【暑假】[实用数据结构]UVa11997 K Smallest Sums
- UVa 11997 K Smallest Sums 优先队列&&打有序表&&归并
- uva 11997 K Smallest Sums