K Smallest Sums
题意:给你k个数组,每个数组里有k个数,然后每个数组里面取出一个数相加会得到一个数,让你求出最小的看的数。
题解:白书的分析:
分析:这题有简化版本的,即2个整数数组A,B,包含K个元素,在每个数组中取一个元素加起来,可以得到k^2个和,求这些和中最小的K个值。
我们需要把这k^2个和组织成如下k个有序表.
表1:A1+B1<=A1+B2<=......<=A1+Bk
表2: A2+B1<=A2+B2<=......<=A2+Bk
表k:Ak+B1<=AK+B2<=......<=Ak+Bk
我们可以用二元组(s,b)来表示一个元素即s=Aa+Bb;为什么不保存A的下标a呢?因为我们用不到a的值。如果我们需要元素(s,b)在表a的下一个元素(s',b+1).只需要计算s'=s+B[b+1]-B[b];
思想感觉就是DP。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int a[][];
int k;
int ans[];
struct Node{
int s;
int id;
bool operator<(const Node a)const {
return s>a.s;
}
};
void merge(int a[],int b[]){
priority_queue<Node>Q;
for(int i=;i<=k;i++){
Node tt;
tt.s=a[i]+b[];
tt.id=;
Q.push(tt);
}
for(int i=;i<=k;i++){
Node temp=Q.top();
Q.pop();
ans[i]=temp.s;
Node t2;
int num=temp.id;
if(num<k){
t2.s=temp.s-b[num]+b[num+];
t2.id=num+;
Q.push(t2);
}
}
}
int main(){
while(~scanf("%d",&k)){
memset(a,,sizeof(a));
memset(ans,,sizeof(ans));
for(int i=;i<=k;i++){
for(int j=;j<=k;j++)
scanf("%d",&a[i][j]);
sort(a[i]+,a[i]+k+);
}
merge(a[],a[]);
for(int i=;i<=k;i++)
merge(ans,a[i]);
for(int i=;i<k;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[k]);
}
}
K Smallest Sums的更多相关文章
- UVA-11997 K Smallest Sums
UVA - 11997 K Smallest Sums Time Limit: 1000MS Memory Limit: Unknown 64bit IO Format: %lld & ...
- D - K Smallest Sums(多路归并+贪心)
Problem K K Smallest Sums You're given k arrays, each array has k integers. There are kk ways to pic ...
- 【暑假】[实用数据结构]UVa11997 K Smallest Sums
UVa11997 K Smallest Sums 题目: K Smallest Sums You're given k arrays, each array has k integers. Ther ...
- 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 id=18702" target="_blank" style="color:blue; text-decoration:none&qu ...
- 优先队列 UVA 11997 K Smallest Sums
题目传送门 题意:训练指南P189 分析:完全参考书上的思路,k^k的表弄成有序表: 表1:A1 + B1 <= A1 + B2 <= .... A1 + Bk 表2:A2 + B1 &l ...
- UVa 11997 (优先队列 多路归并) K Smallest Sums
考虑一个简单的问题,两个长度为n的有序数组A和B,从每个数组中各选出一个数相加,共n2中情况,求最小的n个数. 将这n2个数拆成n个有序表: A1+B1≤A1+B2≤... A2+B1≤A2+B2≤. ...
- uva 11997 K Smallest Sums 优先队列处理多路归并问题
题意:K个数组每组K个值,每次从一组中选一个,共K^k种,问前K个小的. 思路:优先队列处理多路归并,每个状态含有K个元素.详见刘汝佳算法指南. #include<iostream> #i ...
- 【UVA 11997 K Smallest Sums】优先级队列
来自<训练指南>优先级队列的例题. 题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18702 题意:给定 ...
随机推荐
- HDU--5280(dp或枚举)
官方题解: 这个题有非常多O(n2)的算法.这里说一种:枚举每个区间,在枚举区间的同一时候维护区间内的最小值和区间和,将最小值与P的大小进行比較,贪心地取最大值就可以.注意若枚举到的区间是整个数组,则 ...
- POJ1330Nearest Common Ancestors——近期公共祖先(离线Tarjan)
http://poj.org/problem? id=1330 给一个有根树,一个查询节点(u,v)的近期公共祖先 836K 16MS #include<iostream> #includ ...
- ★ Linked List Cycle II -- LeetCode
证明单链表有环路: 本文所用的算法 能够 形象的比喻就是在操场其中跑步.速度快的会把速度慢的扣圈 能够证明,p2追赶上p1的时候.p1一定还没有走完一遍环路,p2也不会跨越p1多圈才追上 我们能够 ...
- 关于 Android 进程保活,你所需要知道的一切
早前,我在知乎上回答了这样一个问题:怎么让 Android 程序一直后台运行,像 QQ 一样不被杀死?.关于 Android 平台的进程保活这一块,想必是所有 Android 开发者瞩目的内容之一.你 ...
- Android开发:最详细的 NavigationDrawer 开发实践总结
最详细的 NavigationDrawer 开发实践总结 继前面写的两篇文章之后(有问题欢迎反馈哦): Android开发:Translucent System Bar 的最佳实践 Android开发 ...
- Android4.0的Alertdialog对话框,设置点击其他位置不消失
Android4.0以上AlertDialog,包括其他自定义的dialog,在触摸对话框边缘外部,对话框消失. 可以设置这么一条属性,当然必须先AlertDialog.Builder.create( ...
- 怎么让自己的java系统使用支付接口
昨天花了好久的时间学习了支付接口的教,我看了前7集,就够用了,大家上网搜索一下传智播客在线支付还不错. 1.一开始有一个form表单 2.这个表单是他帮你写好的,有很多银行,银行的name都是特定的 ...
- EF 更新数据出现 System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: 异常
EF6更新 数据出现 System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: Store update, insert, or ...
- java——输入流FileInputStream
写一个简单的程序,实现从电脑中的一个盘里的文件中往程序中输入内容. package com.liaojianya.chapter5; import java.io.FileInputStream; i ...
- extend简单用法
eg:var obj1=[{a:1,b:2},{a:2,b:3}] var obj2=[{c:3,d:2},{c:4,d:3}] var resultArray=[]; for (var i = 0; ...