UVa11997 K Smallest Sums 归并 + 优先队列

来源:互联网 发布:宏正软件 编辑:程序博客网 时间:2024/05/16 04:14




朴素算法O(n ^ n)啊,这都能做,想了想,最后只要输出其中和的前k小的就行了,有很多计算是冗余的啊,想了想,每行排个序,然后只算前两列,还有2 ^ k个,取k个绰绰有余了,O(2 ^ n),还能骗点分……扇自己一巴掌,卧槽你以为做PAT呢,还能骗分,然而还是忍不住交了一发……


WA代码:


#include <cstdio>#include <cstring>#include <algorithm>#include <map>#include <iostream>#include <set>#include <queue>#include <string>#include <vector>using namespace std;struct node {int psum;node() {}node(int psum) : psum(psum) {}bool operator < (const node &on) const {return this->psum > on.psum;}};int k, cnt;int a[755][755];priority_queue<node> Q;void dfs(int dep, int sum) {if (cnt == 1000000) {return;}if (dep == k) {Q.push(node(sum));cnt++;return;}dfs(dep + 1, sum + a[dep][0]);dfs(dep + 1, sum + a[dep][1]);}int main(){while (~scanf("%d", &k)) {for (int i = 0; i < k; i++) {for (int j = 0; j < k; j++) {scanf("%d", &a[i][j]);}sort(a[i], a[i] + k);}while (!Q.empty()) Q.pop();cnt = 0;dfs(0, 0);int c = 0;while (!Q.empty()) {printf(c++ == 0 ? "%d" : " %d", Q.top());Q.pop();if (c == k) break;}puts("");}return 0;}


没仔细想还有没有别的什么错误,不过这O(2 ^ k)的复杂度肯定是不行的……


其实我只想到了一个起点,没想到归并,一列一列往下合并,横向地去求而不是纵向的,不断地往最小堆里扔,每次取最小的再合并再扔,最后时间复杂度O(n²logn)


#include <cstdio>#include <cstring>#include <algorithm>#include <map>#include <iostream>#include <set>#include <queue>#include <string>#include <vector>using namespace std;struct node {int a, b;node() {}node(int a, int b) : a(a), b(b) {}bool operator < (const node& on) const {return this->a > on.a;}};int A[755][755], C[755];int n;priority_queue<node> Q;void Merge(int *A, int *B, int *C) {while (!Q.empty()) Q.pop();for (int i = 0; i < n; i++) {Q.push(node(A[i] + B[0], 0));}for (int i = 0; i < n; i++) {node tn = Q.top(); Q.pop();int a = tn.a, b = tn.b;C[i] = a;if (b + 1 < n) Q.push(node(a - B[b] + B[b + 1], b + 1));}}int main(){while (~scanf("%d", &n)) {for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {scanf("%d", &A[i][j]);}sort(A[i], A[i] + n);}memcpy(C, A[0], sizeof(A[0]));for (int i = 1; i < n; i++) {Merge(C, A[i], C);}printf("%d", C[0]);for (int i = 1; i < n; i++) {printf(" %d", C[i]);}puts("");}return 0;}





0 0