传送门

Description

Input

Output

Translation

·  给定k个长度为k的数组,把每个数组选一个元素加起来,这样共有kk种可能的答案,求最小的k个

Sample Input


Sample Output

 

Hint

k<=750

Solution

  显然可以一行一行做,同时如果S+now[j]最小,需要S最小。即我们只需要记录前i行的最小的k个ans,分别与当前行的k个相加,从k2个ans中选择前k个小的记录。显然前k小的可以开一个大根堆维护。即如果size>k则pop。这样一共有k次转移,每次转移有k2个状态,维护k的堆的复杂度为Logk,这样总复杂度为O(k3logk)

  易于通过数学归纳证明取第i行的最小的只需要与前i-1行最小的k个ans相加得到。这样我们不妨用数组ans记录前i行最小的k个ans,现在我们考虑我们有两个数组a,b,需要取k个ans最小。不妨设a和b都是有序的,我们显然有如下关系:

  a1+b1≤a1+b2≤a1+b3≤a1+b4≤……≤a1+bk

  a2+b1≤a2+b2≤a2+b3≤a2+b4≤……≤a2+bk

  ……

  ak+b1≤ak+b2≤ak+b3≤ak+b4≤……≤ak+bk

这样显然ai+bj可能成为前k小的ans当且仅当ai+bj-1是前k小的ans。

我们维护一个可能成为ans的序列,每次取这个序列中最小,显然最小值可以成为合法的ans。同时不妨设这个值为ai+bj,那么我们将ai+bj+1压入序列,因为它可能成为合法的ans。

初始化上,因为ai+b1可能成为合法的ans,我们将这k个全部压入队列中。

Code

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1010 inline void qr(int &x) {
char ch=getchar(),lst=NULL;
while(ch>''||ch<'') lst=ch,ch=getchar();
while(ch>=''&&ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
if(lst=='-') x=-x;
} template <typename T>
inline T mmax(const T &a,const T &b) {if(a>b) return a;return b;}
template <typename T>
inline T mmin(const T &a,const T &b) {if(a<b) return a;return b;}
template <typename T>
inline T mabs(const T &a) {if(a>=) return a;return -a;} template <typename T>
inline void mswap(T &a,T &b) {T temp=a;a=b;b=temp;} int k,MU[maxn],ans[maxn]; struct Zay {
int v,s;
Zay(int a=,int b=) {v=a;s=b;}
inline bool operator <(const Zay &others) const{return this->v>others.v;}
}; std::priority_queue<Zay>Q;
void clear(); int main() {
while(~scanf("%d",&k)) {
clear();
for(int i=;i<=k;++i) qr(ans[i]);
for(int i=;i<=k;++i) {
memset(MU,,sizeof MU);
for(int j=;j<=k;++j) {
qr(MU[j]);
}
std::sort(MU+,MU++k);
while(!Q.empty()) Q.pop();
for(int j=;j<=k;++j) {
Q.push(Zay(ans[j]+MU[],));
}
for(int j=;j<=k;++j) {
Zay temp=Q.top();Q.pop();
ans[j]=temp.v;
if(temp.s<k) Q.push(Zay(temp.v-MU[temp.s]+MU[temp.s+],temp.s+));
}
}
for(int i=;i<k;++i) printf("%d ",ans[i]);printf("%d\n",ans[k]);
}
return ;
} void clear() {
memset(ans,,sizeof ans);
}

Summary

在堆的应用中,维护一坨可能合法的解进行操作,是一种常用的思路。比如本题和dijkstra算法都是这个思路。这一坨合法的解一般满足下面两个条件:

第一,这坨解中最大/小的解一定是合法的解。比如本题中,序列中最小的一定是合法的解,dijkstra算法中,堆中权值和最小的解一定是到该点的最短路等等

第二,通过寻找合法解,可以获得其他可能解。比如在本题中,ai+bj合法时,ai+bj+1是可能解。在dijkstra算法中,找到到一个点的最短路可以更新和它相邻的点的可能最短路压入堆中。

【优先队列】【UVa11997】K Smallest Sums的更多相关文章

  1. 【暑假】[实用数据结构]UVa11997 K Smallest Sums

    UVa11997 K Smallest Sums  题目: K Smallest Sums You're given k arrays, each array has k integers. Ther ...

  2. UVA-11997 K Smallest Sums

    UVA - 11997 K Smallest Sums Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & ...

  3. uva11997 K Smallest Sums&&UVALive 3135 Argus(优先队列,多路归并)

    #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #inc ...

  4. UVA11997 K Smallest Sums

    思路 经典的k路归并问题 问题先转换为2路的有序表归并 先让A[1~k]都和B[1]相加,然后加入堆中,取出堆顶(A[x]+B[y])之后,再放入A[x]+B[y+1] 代码 #include < ...

  5. 题解——UVA11997 K Smallest Sums

    题面 背景 输入 输出 翻译(渣自翻) 给定K个包含K个数字的表,要求将其能产生的\( k^{k} \)个值中最小的K个输出出来 题解 k路归并问题的经典问题 可以转化为二路归并问题求解 考虑A[], ...

  6. 11997 - K Smallest Sums(优先队列)

    11997 - K Smallest Sums You’re given k arrays, each array has k integers. There are kk ways to pick ...

  7. UVa 11997 K Smallest Sums 优先队列&amp;&amp;打有序表&amp;&amp;归并

    UVA - 11997 id=18702" target="_blank" style="color:blue; text-decoration:none&qu ...

  8. 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 ...

  9. 优先队列 UVA 11997 K Smallest Sums

    题目传送门 题意:训练指南P189 分析:完全参考书上的思路,k^k的表弄成有序表: 表1:A1 + B1 <= A1 + B2 <= .... A1 + Bk 表2:A2 + B1 &l ...

随机推荐

  1. GIt学习第二天之版本回退、工作区和暂存区

    搬运自 ‘廖雪峰的官方网站’ 地址:https://www.liaoxuefeng.com/ 1.版本回退 在Git中,我们用git log命令显示从最近到最远的提交日志,如果嫌输出信息太多,看得眼花 ...

  2. TPO-14 C1 Locate a political book

    TPO-14 C1 Locate a political book 第 1 段 1.Listen to a conversation between the student and librarian ...

  3. 了解Python控制流语句——if语句

    控制流 截止到现在,在我们所看过的程序中,总是有一系列语句从上到下精确排列,并交由 Python 忠实地执行.如果你想改变这一工作流程,应该怎么做?就像这样的情况:你需要程序作出一些决定,并依据不同的 ...

  4. vs_code 快捷键

    一般的Ctrl+Shift+P,F1显示命令面板按Ctrl+P快速打开,到文件.Ctrl + Shift + N新窗口/实例Ctrl + Shift + W /关闭窗口实例Ctrl +.用户设置Ctr ...

  5. Elasticsearch 评分score计算中的Boost 和 queryNorm

    本来没有这篇文章,在公司分享ES的时候遇到一个问题,使用boost的时候,怎么从评分score中知道boost的影响. 虽然我们从查询结果可以直观看到,boost起了应有的作用,但是在explain的 ...

  6. 基于深度学习的中文语音识别系统框架(pluse)

    目录 声学模型 GRU-CTC DFCNN DFSMN 语言模型 n-gram CBHG 数据集 本文搭建一个完整的中文语音识别系统,包括声学模型和语言模型,能够将输入的音频信号识别为汉字. 声学模型 ...

  7. windows store无法登陆的问题解决方案

    Windows应用商店或商店Apps无法打开或闪退的可选方法 (仅用于10565之前的Windows 10版本) 右键点击任务栏,选择"属性",切换到"导航"选 ...

  8. 创新手机游戏《3L》开发点滴(3)——道具、物品、装备表设计 V2(最终版)

    我们正在开发一款新手游,里面有道具,之前也写了一篇博文记录了下我们的设计思路,但是国庆到了,于是我有了时间继续纠结这个问题. 其实我主要是在到底是用mysql还是mongodb上纠结.这个复杂.痛苦. ...

  9. Centos6设置DNS

    通过编辑 vi /etc/resolv.conf 设置首选DNS和次要DNS.如下,排在前面的就是首选DNS,后面一行就是次要的DNS服务器DNS vi /etc/resolv.conf namese ...

  10. js经典试题之w3规范系列

    js经典试题之w3规范系列 1:w3c 制定的 javascript 标准事件模型的正确的顺序? 答案:事件捕获->事件处理->事件冒泡 解析:先事件捕获从windows > doc ...