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
- UVa11997 K Smallest Sums 归并 + 优先队列
- UVA11997 - K Smallest Sums 优先队列,多路归并
- uva11997 K Smallest Sums(优先队列)
- uva11997 K Smallest Sums(优先队列)
- UVA11997 K Smallest Sums(并归,优先队列)
- uva11997 K Smallest Sums
- Uva11997 K Smallest Sums
- uva11997 K Smallest Sums
- 【UVA11997】K Smallest Sums
- UVA - 11997 K Smallest Sums 归并排序+优先队列
- UVA K Smallest Sums(多路归并,优先队列)
- K Smallest Sums(Uva 11997) 多路归并+优先队列
- UVA11997-多路归并排序-K Smallest Sums
- UVa 11997 K Smallest Sums (优先队列 & k路归并化为两两归并)
- uva11997(优先队列,归并)
- (优先队列)K Smallest Sums
- UVa 11997 K Smallest Sums / 优先队列
- UVA 11997 K Smallest Sums 优先队列
- Build a Responsive UI with ConstraintLayout
- 杭电ACM1000题------java语言
- Linux学习之网络基础
- cmsplus实战之仿[我扫网]之四:安装整站下载器并下载仿站所有数据
- Linux文件与时间编程2
- UVa11997 K Smallest Sums 归并 + 优先队列
- 278. First Bad Version
- noip2012疫情控制
- BNU Problem A Best Matched Pair
- C#入门
- EDA软件_Cadence软件使用教程视频学习笔记
- poj 2828 Buy Tickets
- shell编程笔记
- Spring batch批处理框架