【UVA 11997 K Smallest Sums】优先级队列
来自《训练指南》优先级队列的例题。
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18702
题意:给定k个整数数组,各包含k个元素。在每个数组中取一个元素加起来,可以得到kk个和,求这些和中最小的k个值(不去重)。
数据范围:k [2, 750]
思路:暴力枚举k^k不可取。
“先来看问题的简化版:给出两个长度为k的数组A和B,分别在A和B中任取一个数并相加,可以得到k^2个和,求这些和中最小的k个。”
首先把A, B从小到大排序。由于只求最小的前k个值,我们可以先假定B[0]与A的k个元素分别相加得到的元素集合S就是最小的k个和,然后每次取出S的最小值Smin保存到结果数组R中,并把Smin减去B[i]、加上B[i+1]后得到的值再放回集合S中,保持S的大小总为k。这样经过k轮取出-放回操作后,R中的k个元素就是结果。我们把这一操作过程叫作A,B的合并。合并一次的复杂度为O(klogk)
S需要k次插入和删除,每次只取最小值,因此数据结构选用完全二叉堆实现的优先级队列很合适。
现在由两个数组A,B扩展到k个数组A1~Ak,只需把A1看作A, 依次处理 i: 2~k,每次把Ai合并到A1中,这样经过k次两两合并后,A1中的k个数就是结果。总的复杂度O(k2logk)
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int MAX_K = ; struct Elem{
int sum, b;
Elem(int s, int b):sum(s), b(b){}
Elem& operator = (const Elem& e){
sum = e.sum;
b = e.b;
return *this;
}
bool operator < (const Elem& e) const{
return sum > e.sum; //小顶堆
}
}; void merge(int* A, int* B, int n){
priority_queue<Elem> pq;
for(int i=; i<n; i++){
pq.push(Elem(A[i] + B[], ));
}
for(int i=; i<n; i++){
Elem e = pq.top();
A[i] = e.sum;
pq.pop();
e.sum = e.sum - B[e.b] + B[e.b+];
e.b = e.b + ;
pq.push(e);
}
// for(int i=0; i<n; i++){
// printf("%d ", A[i]);
// }
// printf("\n");
} int k;
int a[MAX_K], b[MAX_K]; int main()
{
freopen("11997.txt", "r", stdin);
while(~scanf("%d", &k)){
for(int i=; i<k; i++){
scanf("%d", &a[i]);
}
sort(a, a+k);
for(int i=; i<k; i++){
for(int j=; j<k; j++){
scanf("%d", &b[j]);
}
sort(b, b+k);
merge(a, b, k);
}
printf("%d", a[]);
for(int i=; i<k; i++){
printf(" %d", a[i]);
}
printf("\n");
}
return ;
}
【UVA 11997 K Smallest Sums】优先级队列的更多相关文章
- UVa 11997 K Smallest Sums 优先队列&&打有序表&&归并
UVA - 11997 id=18702" target="_blank" style="color:blue; text-decoration:none&qu ...
- UVA 11997 K Smallest Sums 优先队列 多路合并
vjudge 上题目链接:UVA 11997 题意很简单,就是从 k 个数组(每个数组均包含 k 个正整数)中各取出一个整数相加(所以可以得到 kk 个结果),输出前 k 小的和. 这时训练指南上的一 ...
- UVa 11997 K Smallest Sums - 优先队列
题目大意 有k个长度为k的数组,从每个数组中选出1个数,再把这k个数进行求和,问在所有的这些和中,最小的前k个和. 考虑将前i个数组合并,保留前k个和.然后考虑将第(i + 1)个数组和它合并,保留前 ...
- 【UVA–11997 K Smallest Sums 】
·哦,这题要用优先队列?那大米饼就扔一个手写堆上去吧! ·英文题,述大意: 输入n个长度为n的序列(题中是k,2<=k<=750).一种结果定义为:从每个序列中都要挑选一个数加 ...
- 优先队列 UVA 11997 K Smallest Sums
题目传送门 题意:训练指南P189 分析:完全参考书上的思路,k^k的表弄成有序表: 表1:A1 + B1 <= A1 + B2 <= .... A1 + Bk 表2:A2 + B1 &l ...
- uva 11997 K Smallest Sums 优先队列处理多路归并问题
题意:K个数组每组K个值,每次从一组中选一个,共K^k种,问前K个小的. 思路:优先队列处理多路归并,每个状态含有K个元素.详见刘汝佳算法指南. #include<iostream> #i ...
- UVA 11997 K Smallest Sums (多路归并)
从包含k个整数的k个数组中各选一个求和,在所有的和中选最小的k个值. 思路是多路归并,对于两个长度为k的有序表按一定顺序选两个数字组成和,(B表已经有序)会形成n个有序表 A1+B1<=A1+B ...
- 11997 - K Smallest Sums(优先队列)
11997 - K Smallest Sums You’re given k arrays, each array has k integers. There are kk ways to pick ...
- UVA-11997 K Smallest Sums
UVA - 11997 K Smallest Sums Time Limit: 1000MS Memory Limit: Unknown 64bit IO Format: %lld & ...
随机推荐
- 简述tcp协议对http性能的影响及优化
当网站服务器并发连接达到一定程度时,你可能需要考虑服务器系统中tcp协议设置对http服务器的影响. tcp相关延时主要包括: 1.tcp连接时建立握手: 2.tcp慢启动拥塞控制: 3.数据聚集的N ...
- ubuntu 14.04 下 yii2 下载安装
先安装composer ,安装了curl的情况下: curl -s http://getcomposer.org/installer | php mv composer.phar /usr/local ...
- pyqt treeview基础学习
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' from PyQt4.QtGui import * from Py ...
- java 面向过程实现万年历
public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-gener ...
- ubuntu 配置jdk
shawn@e014-anle-lnx:~$ sudo su # chmod 777 jdk-6u27-linux-i586.bin # ./jdk-6u27-linux-i586.bin # mv ...
- bash的元字符(下)
` "Esc"键正下方键,替换命令 PS1=`command` {} 在当前shell中运行命令 {command1;command2} | 创建命令间的管道 command1 | ...
- Android开发实现透明通知栏
这个特性是andorid4.4支持的,最少要api19才可以使用,也就是说如果Android的机子是低于4.4,沉浸通知栏是没有效果的.下面介绍一下使用的方法,非常得简单. public void i ...
- nginx配置文件(反向代理+集群+动静分离)
1.nginx纯反向代理配置(nginx.conf): #user nobody;worker_processes 4;error_log logs/error.log info;pid logs/n ...
- weblogic开机启动脚本
1.在/home/bea/startBeaAll目录内创建一个startBeaAll.sh文件,加入如下内容(把相应目录与命令修改即可,红字部分为修改地方): #!/bin/sh echo " ...
- OpenCV——人脸检测
OpenCV支持的目标检测的方法: 利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification) 1.加载级联分类器 CascadeClass ...