UVA - 11997
|
You’re given k arrays, each array has k integers. There are k^k ways to pick exactly one element in each array and calculate the sum of the integers. Your task is to find the k smallest sums among them.
The question is from here.
My Solution
把每一个数组排序以后打个 有序表
表1: A1 + B1 <= A1+B2 <= A1+B3 <= ``````````
表2: A2 + B1 <= ``````
表3: A3 + B1 <= ``````
第啊张表里的元素形如 Aa + Bb。用(s = Aa+Bb, b) 表示,用s‘ = Aa + B(b+1) =Aa + Bb - Bb + B(b+1) = s - Bb + B(b+1);
#include <iostream> #include <queue> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 760; int A[maxn],B[maxn]; struct Item { int s, b; Item(int s, int b): s(s), b(b) {} bool operator < (const Item& rhs) const { return s > rhs.s; } }; void merge_pro(int* A, int* b, int n) { priority_queue<Item> q; for(int i = 0; i < n; i++) q.push(Item(A[i]+B[0], 0)); for(int i = 0; i < n; i++){ Item item = q.top();q.pop(); A[i] = item.s; int b = item.b; if(b+1 < n) q.push(Item(item.s-B[b]+B[b+1], b+1)); //this "if" judge is really necessary! } } int main() { int n; while(scanf("%d", &n) == 1){ for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ if(i == 0) scanf("%d", &A[j]); else scanf("%d", &B[j]); } if(i == 0)sort(A, A+n); else sort(B, B+n); if(i != 0) merge_pro(A, B, n); } printf("%d", A[0]); for(int i = 1; i < n; i++) printf(" %d", A[i]); printf(" "); } return 0; }
Thank you!