NKOJ-3765 k个最小和
来源:互联网 发布:淘宝哪家近视眼镜店好 编辑:程序博客网 时间:2024/06/10 02:18
P3765k个最小和
时间限制 : - MS 空间限制 : 65536 KB
评测说明 : 时限1000ms
问题描述
有k个整数数组,各包含k个元素,从每个数组中选取一个元素加起来,可以得到k^k个和,求这些和中最小的k个值。
输入格式
第一行,一个整数k(k<=500)接下来k行,每行k个正整数(<=1000000)
输出格式
一行,k个有小到大排列的整数,表示最小的k个和
样例输入 1
3 1 8 5 9 2 5 10 7 6
样例输出 1
9 10 12
样例输入 2
2 1 1 1 2
样例输出 2
2 2
提示
样例1说明:选出的三组数分别是(1 2 6) (1 2 7) (1 5 6)
来源 改编自uva11997
no fuck to say
题解
其实这道题目没什么特别难的
我说一个词 优先队列
是不是感觉抓到了一点东西
详细解法
首先简化题目 假设只有两个数列
数列1 2 5 3 7 8 9数列2 5 8 6 4 7 5和题目中要求一样 求各取一个元素后的最小和解法十分简单排个序数列1 2 3 5 7 8 9数列2 4 5 5 6 7 8优先队列 存入数列1每一个数字加上数列2中最小数字的和即 加入 2+4 3+4 5+4 7+4 8+4 9+4这个时候毋庸置疑 2+4是最小的
接下来的操作十分重要
将 2+4取出 并加入 2+5 即加入 第一列第一个数字 + 第二列第一个数字
为什么这么做呢?
首先 你能保证当前队列中的最小值一定是最小的因为当前数列中的数字是数列1当中的数字 加上 数列2中最小的数字的和第二列没有数字能使这些和更小但是取出 2+4 之后 你需要做的是 使包含2的项继续存在于队列中对于 2 来讲 它的和的大小排列为2+4 2+5 2+5 2+6 2+7 2+8取出了2+4之后 就应该加入 2+5 因为这是次大的
解释的并不是很清楚 反正就是使数列1中的每一项都有一个最小和在单调队列中
你当前取出了它的最小和 就要加入它的次小和
所以说 单调队列中的项其实使 数列1中的每一个数字 加上当前它能够加上的最小的数列2中的数字 产生的当前的最小和
之所以要说使能够加上的 是因为之前已经加过的就不能加了
以此类推
将两行数列和中的前k个数存入 数组1 当中
然后将第三行的数字存入数组2
再次操作之后就得出了前三行数字相加得到的前k小值
于是在不停的重复之后 最后得到的就是k行和的最小值
附上对拍代码
#include <iostream>#include <cstdio>#include <algorithm>#include <queue>using namespace std;inline int input(){ char c=getchar();int o; while(c>57||c<48)c=getchar(); for(o=0;c>47&&c<58;c=getchar())o=(o<<1)+(o<<3)+c-48; return o;}int A[512],B[512],sum=0,k,pos;struct nums{ int n,p; bool operator <(const nums& b)const { return n>b.n; }}add;void remove(){ priority_queue<nums>st;add.p=1; for(int i=1;i<=k;i++)add.n=A[i]+B[1],st.push(add); A[1]=st.top().n; add=st.top();st.pop(); add.p=2;add.n+=(B[2]-B[1]); st.push(add); for(int p=2;p<=k;p++) { add=st.top();st.pop(); A[p]=add.n; add.n+=(B[add.p+1]-B[add.p]);add.p++; if(add.p<=k)st.push(add); }}int main(){ k=input(); for(int a=1;a<=k;a++)A[a]=input(); sort(A+1,A+k+1); for(int a=2;a<=k;a++) { for(int b=1;b<=k;b++)B[b]=input(); sort(B+1,B+k+1); remove(); } for(int i=1;i<=k;i++)printf("%d ",A[i]);}
阅读全文
0 0
- 【题】NKOJ 3765 k个最小和
- NKOJ-3765 k个最小和
- B(UVA-11997)k个最小和
- UVA 11997 K个最小和
- 例题3.4 K个最小和 UVa11997
- K个最小和(K Smallest Sums)
- k个最小和 K路归并问题
- UVa 11997 K个最小和(训练指南)
- 算法---K个最小和(讲解的思路不清晰)
- 第三章例题4 k个最小和
- 最小的k个元素
- 求K个最小元素
- 最小的k个数字
- k个最小的数
- 求最小的k个数字和求第k小的数字
- 算法之查找第k小的数和查找最小的k个元素
- UVA11997:K Smallest Sums(多路归并求最小k个和)
- UVA11997 K个最小和_优先队列&&K路合并
- 搭建JSP运行环境(Eclipse for java EE Developers+Tomcat7.0.79)
- 使用Lock,wait/notify,Semaphore三种方式实现多线程通信
- HDU3746 Cyclic Nacklace(KMP,最小循环节)
- LeetCode——60. Permutation Sequence
- 2017-09-13 LeetCode_241 Different Ways to Add Parentheses
- NKOJ-3765 k个最小和
- 利用RealSense检测到的手指关节信息自定义简单动态手势
- iptables防御抵御CC攻击(抵御少量肉机)暨ipset的使用
- 2017-09-13 LeetCode_282 Expression Add Operators
- Django实现一对多表模型的跨表查询
- 01背包问题
- Codeblocks进行C/C++开发
- poj2251 BFS大法好
- opencv学习笔记(一) 使用opencv进行拍照