北京集训TEST13——PA(第k小数)
题目:
Description
【问题描述】
从n个数中选若干(至少1)个数求和,求所有方案中第k小的和(和相同但取法不同的视为不同方案)。
【输入格式】
第一行输入2个正整数n,k。
第二行输入这n个正整数。
【输出格式】
输出第k小的和。
【样例输入】
5 12
1 2 3 5 8
【样例输出】
8
【样例解释】
前12小的和分别为:1 2 3 3 4 5 5 6 6 7 8 8
【数据规模和约定】
测试点1,n<=16。
测试点2-3,n<=100,k<=500。
测试点4-5,n<=1000,k<=5000。
测试点6-8,n<=10^5,k<=5*10^5。
测试点9-10,n<=35。
对于所有数据,1<=k<2^n,n个正整数每个都不超过10^9。
题解:
心得:
优先队列是个好东西,折半搜索是个好东西;
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cctype>
#include<queue>
using namespace std;
const int N=;
const int M=1e7+;
struct node
{
long long sum;
int pos;
node(long long sum,int pos):sum(sum),pos(pos){}
};
inline bool operator < (const node &a,const node &b)
{
return a.sum>b.sum;
}
priority_queue<node>que;
long long num[N];
long long vala[M],valb[M];
long long k;
int tota=,totb=;
int n;
void solve1()
{
que.push(node(num[],));
for(int i=;i<k;i++)
{
long long tsum=que.top().sum;
int tpos=que.top().pos;
que.pop();
if(tpos<=n)
{
que.push(node(tsum-num[tpos-]+num[tpos],tpos+));
que.push(node(tsum+num[tpos],tpos+));
}
}
printf("%lld\n",que.top().sum);
}
void dfs1(int u,int des,long long val)
{
if(u>des)
{
if(val)
vala[++tota]=val;
}
else
{
dfs1(u+,des,val+num[u]);
dfs1(u+,des,val);
}
}
void dfs2(int u,int des,long long val)
{
if(u>des)
if(val)
valb[++totb]=val;
else
{
dfs2(u+,des,val+num[u]);
dfs2(u+,des,val);
}
}
bool jud(long long val)
{
long long temp=;
int j=;
for(int i=tota;i>=;i--)
{
if(vala[i]>val) continue;
for(;j<=totb&&vala[i]+valb[j]<=val;j++);
temp+=j;
}
return temp>k;
}
void solve2()
{
dfs1(,n/,);
dfs2(n/+,n,);
sort(vala+,vala+tota+);
sort(valb+,valb+totb+);
long long l=,r=0x3f3f3f3f3f3f3f3f;
while(l<=r)
{
long long mid=(l+r)/;
if(jud(mid)) r=mid-;
else l=mid+;
}
printf("%lld\n",r+);
}
int main()
{
scanf("%d%lld",&n,&k);
for(int i=;i<=n;i++)
scanf("%lld",&num[i]);
sort(num+,num+n+);
long long j=0x3f3f3f3f3f3f3f3f;
if(n>) solve1();
else solve2();
}
北京集训TEST13——PA(第k小数)的更多相关文章
- 北京集训TEST13——PA(Goodness)
题目: Description 桌面上放有 n 张卡牌.对于每张卡牌,一面是绿色的,另一面是红色的.卡牌的每一面都标有一个整数.对于卡牌a和卡牌b,卡牌a对卡牌b的好感度为卡牌a绿色面的数与卡牌b红色 ...
- 北京集训TEST12——PA( Mortal Kombat)
题目: Description 有一天,有N个外星人企图入侵地球.地球派出全球战斗力最强的M个人代表人类对抗外星人.根据外星的战斗规则,每个外星人应该分别与一名地球人对战(不同的外星人要与不同的地球人 ...
- 求两个有序序列合并成新有序序列的中位数,求第k小数
此算法涉及一个重要数学结论:如果A[k/2-1]<B[k/2-1],那么A[0]~A[k/2-1]一定在第k小的数的序列当中,可以用反证法证明. 算法思想如下: 1,假设A长度为m,B长度为n, ...
- 第K 小数
[问题描述]有两个正整数数列,元素个数分别为N和M.从两个数列中分别任取一个数相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少.[输入格式]输入文件名为number.in.输入文件包 ...
- 数组第K小数问题 及其对于 快排和堆排 的相关优化比较
题目描述 给定一个整数数组a[0,...,n-1],求数组中第k小数 输入描述 首先输入数组长度n和k,其中1<=n<=5000, 1<=k<=n 然后输出n个整形元素,每个数 ...
- Bsoj 1322 第K小数
第K小数 Description 现在已有N个整数,你有以下三种操作: 1 A:表示加入一个值为A的整数: 2 B:表示删除其中值为B的整数: 3 K:表示输出这些整数中第K小的数: Input 第一 ...
- 算法打基础——顺序统计(找第k小数)
这次主要是讲如何在线性时间下找n个元素的未排序序列中第k小的数.当然如果\(k=1 or k=n\),即找最大最小 数,线性时间内遍历即可完成,当拓展到一般,如中位数时,相关算法就值得研究了.这里还要 ...
- 查找第K小数
题目描述 查找一个数组的第K小的数,注意同样大小算一样大. 如 2 1 3 4 5 2 第三小数为3. 输入描述: 输入有多组数据.每组输入n,然后输入n个整数(1<=n<=1000), ...
- OJ2237第k小数题解
题目描述: 有n个数,请你找出第k小的数. 输入描述: 第一行有2个正整数n,k(n,k<=10^7)第二行有n个非负数ai(ai<=10^5) 输出描述: 输出第k小的数. 输入样例: ...
随机推荐
- HDU 5092 Seam Carving (dp)
题意,给一个数字矩阵,要求从上往下的一条路径,使这条路径上数字之和最小,如有多条输出最靠右的一条. 数字三角形打印路径... 一般打印路径有两种选择,一是转移的时候加以记录,二是通过检查dp值回溯. ...
- XPath语法规则及实例
XPath语法规则及实例 XPath语法规则 一.XPath术语: 1.节点:在XPath中,有七种类型的节点:元素.属性.文本.命名空间.处理指令.注释以及文档(根)节点. XML文档是被作为节点树 ...
- falling object思路总结
1.用检测的方法把falling object标记为一个类别,然后检测出类别.这种方式不可行的原因:因为falling object可能是任何东西,所以可能是一个路锥,也可能是一个玻璃瓶,还可能是掉下 ...
- pycharm 使用技巧
格式化代码为pep8: ctrl+alt+l http://edu.51cto.com//index.php?do=lession&id=163794
- 标签input的value属性和placeholderde 区别
placeholder 顾名思义是一个占位符 在你的value为空的时候他才会显示出来,但是他本身并不是value,也不会被表单提交.
- cocos2dx lua 吞噬层的触摸事件
首先要创建一个layer,设置该层为可触摸 layer:setTouchEnabled(true) 注册触摸事件 local listener = cc.EventListenerTouchOneBy ...
- SVN:The working copy is locked due to a previous error (一)
使用 Cornerstone 时,碰到如题问题,SVN无法Update.Commit等操作. 解决办法:Working Copies ⟹ '右键' ⟹ Clean 即可解决! 尊重作者劳动成果,转载 ...
- C#基础-判断语句
switch语句 Console.WriteLine("请输入月份"); string strInput = Console.ReadLine(); switch(strInput ...
- ubuntu18.04+win10解决时钟不同步办法
安装ntpdate: 执行命令: sudo apt-get install ntpdate 设置校正服务器: sudo ntpdate time.windows.com 设置硬件时间为本地时间: 执行 ...
- 01Qt中的隐式共享
隐式共享 隐式共享又称为回写复制(copy on write).当两个对象共享同一分数据时(通过浅拷贝实现数据共享),如果数据不改变,则不进行数据的复制.而当某个对象需要需要改变数据时,则进行深拷 ...