UVA 11997 K Smallest Sums(优先队列)
来源:互联网 发布:移动网络解锁 编辑:程序博客网 时间:2024/06/05 16:27
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3148
题意:给定k个数组,每个数组k个数,对于每个数组只取一个数,这样总共有k^k种选择,每种选择对应一个和,这样总共有k^k个和,现在求这个k^k个和中的前k小个。
思路:一开始想的利用优先队列+BFS的方法,即每次记录当前在每个数组中选取的位置,然后由此扩展k次。交了一发然后T了。后来仔细想了想发现是时间复杂度算错了,虽然看似是O(k^2 * logk)的复杂度,但是我的式子中的k并不是题目中所给出的范围,应该比实际更大一些,因为没次丢入优先队列就是一个logk(k是队列中元素个数)的复杂度,而相对我的算法k将会逐渐增大。改进后的算法则是,可以不用k个数组一起扩展,每次扩展2个数组并将2个数组得到的k^2个和的前k个存起来继续与另外的数组扩展。这样最后这k个值就是最后的答案。
代码:
#include <iostream>#include <stdio.h>#include <algorithm>#include <queue>using namespace std;const int N = 1e3 + 10;struct Node { int sum, id; Node() {} Node(int s, int i) { sum = s; id = i; } friend bool operator < (Node a, Node b) { return a.sum > b.sum; }};int a[N][N];int k;void solve(int u, int v, int t) { priority_queue<Node> q; for (int i = 0; i < k; i++) q.push(Node(a[u][i] + a[v][0], 0)); for (int i = 0 ; i < k; i++) { Node f = q.top(); q.pop(); a[t][i] = f.sum; if (f.id < k - 1) q.push(Node(f.sum + a[v][f.id + 1] - a[v][f.id], f.id + 1)); }}int main() { while (scanf("%d", &k) != EOF) { 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); } for (int i = 1; i < k; i++) solve(0, i, 0); for (int i = 0; i < k -1 ; i++) printf("%d ", a[0][i]); printf("%d\n", a[0][k - 1]); } return 0;}
0 0
- UVa 11997 K Smallest Sums / 优先队列
- UVA 11997 K Smallest Sums 优先队列
- UVA 11997 K Smallest Sums(优先队列)
- uva 11997 - K Smallest Sums(优先队列)
- UVA 11997 - K Smallest Sums 优先队列
- uva 11997 K Smallest Sums 优先队列
- UVa 11997 K Smallest Sums (优先队列)
- UVA 11997 K Smallest Sums(优先队列)
- UVA 11997 K Smallest Sums(优先队列)
- UVA 11997 K Smallest Sums(优先队列)
- K Smallest Sums uva+优先队列
- UVA 11997 - K Smallest Sums(优先队列+多路合并)
- UVA - 11997 K Smallest Sums 归并排序+优先队列
- 【优先队列之多路合并】UVA - 11997 K Smallest Sums
- K Smallest Sums(Uva 11997) 多路归并+优先队列
- UVa - 11997 K Smallest Sums(优先队列多路归并)
- (UVa 11997)K Smallest Sums --多路归并问题,优先队列
- (优先队列)K Smallest Sums
- 设计模式之外观模式
- BresenhamLine
- 命令行和界面程序同时使用
- 读取或设置BIOS时间
- servlet生命周期和工作原理
- UVA 11997 K Smallest Sums(优先队列)
- 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决
- Servlet生命周期
- MidpointCircle
- OC类方法和对象方法对比
- 第三周项目1 顺序表得基本运算(1)
- 我的第一份工作的得与失
- 动图
- 顺序表应用(2)