题意:

给定一个数组,数组中元素一共为n个,将这 n 个元素放入集合中,要求 按照子集中元素累计值 从小到大的方式 输出排序为第 k 的子集的累加值。

思路:

这应该属于一类经典问题。

我们先来回忆一下如何枚举所有子集的情况,可以用 dfs 依次枚举所有的情况。

那我们再来思考一下如何用最小的时间复杂度,将这么多种情况进行排序输出。

首先肯定是要对数组进行排序的,然后用优先队列维护一个 pair 类型的序列。

   第一次先将 make_pair( a[1] , 1 ) 扔到队列中,然后循环到第二次的时候,先将队列首的元素 pair( ans , idx ) 弹出队列。

然后如果 idx < n,再将 pair( ans+a[idx+1] , idx+1 ) 和 pair( ans-a[idx]+a[idx+1] , idx+1 ) 扔进队列中,这样就可以满足不会有重复元素,而且可以枚举集合中所有组合情况,并且可以保证之后扔进队列的数绝对不会比现在要扔进去的这两个数更大,因此可以满足题意。

这种对子集进行排序的输出方式非常美妙,并且非常经典,必须掌握!

代码:【题目代码】

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#define rep(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
typedef long long LL;
const int N = 1e6+10;priority_queue<pair<LL,int>, vector<pair<LL,int> >, greater<pair<LL,int> > > q;
int n,k;
LL a[N];void solve()
{while(q.size()) q.pop();int cnt = 0;q.push(make_pair(a[1],1));while(cnt < k){pair<LL,int> tmp = q.top();q.pop();LL ans = tmp.first;int idx = tmp.second;if(idx < n){q.push(make_pair(ans+a[idx+1],idx+1));q.push(make_pair(ans-a[idx]+a[idx+1],idx+1));}cnt++;if(cnt == k){printf("%lld\n",ans);}}
}int main()
{while(~scanf("%d%d",&n,&k)){rep(i,1,n) scanf("%lld",&a[i]);sort(a+1,a+1+n);solve();}return 0;
}

代码:【此种枚举方式的正确性证明】

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#define rep(i,a,b) for(int i = a;i <= b;i++)
using namespace std;int a[20] = {0,1,4,3,5,2,6,7,8,9,10};int cnt = 0;priority_queue<pair<int,int>, vector<pair<int,int> >, greater<pair<int,int> > > q;//dfs用于全组合问题中 “将所有组合方式枚举出来”
void dfs(int x,int step)
{if(step == 11){printf("cnt:%d,x:%d\n",++cnt,x);return;}if(x != 0){dfs(x*a[step],step+1);dfs(x,step+1);} else{dfs(a[step],step+1);dfs(0,step+1);}
}int main()
{dfs(0,1);cnt = 0;printf("\n\n\n");/*    优先队列用于将全组合中所有数按照从小到大的顺序进行输出优先队列中的值代表 pair(ans,idx) 此处 idx 代表ans中最大的那个数的下标每次更新的时候,加入 pair(ans+a[idx+1],idx+1) 和 pair(ans-a[idx]+a[idx+1],idx+1)注意:用优先队列求出全组合的所有数的时候,必须先对数组中的数进行排序只有排序了才能保证这种取法每次取出的都是最小的
*/sort(a+1,a+1+10);while(q.size()) q.pop();q.push(make_pair(a[1],1));while(q.size()){pair<int,int> tmp = q.top();int ans = tmp.first;int idx = tmp.second;q.pop();if(idx < 10){q.push(make_pair(ans*a[idx+1],idx+1));q.push(make_pair(ans*a[idx+1]/(a[idx+1]),idx+1));}printf("cnt:%d,x:%d\n",++cnt,ans);}return 0;
}

【Gym - 101234G】Dreamoon and NightMarket 【子集中第K大元素】相关推荐

  1. iframe父页面获取iframe子页面的元素 与 iframe子页面获取父页面元素

    一.在iframe子页面获取父页面元素代码如下:$('#objld', parent.document); 二.在父页面获取iframe子页面的元素代码如下:$("#objid", ...

  2. Java黑皮书课后题第8章:***8.35(最大块)给定一个元素为0或者1的方阵,编写程序,找到一个元素都为1的最大的子方阵。程序提示用户输入矩阵的行数。然后显示最大的子方阵的第一个元素、行数

    ***8.35(最大块)给定一个元素为0或者1的方阵,编写程序,找到一个元素都为1的最大的子方阵.程序提示用户输入矩阵的行数.然后显示最大的子方阵的第一个元素.行数 题目 题目描述与运行示例 破题 代 ...

  3. jQuery子页面获取父页面元素

    $("input[type='checkbox']:checked",window.opener.document);//适用于打开窗口的父页面元素获取 $("input ...

  4. 正则表达式之子表达式 ‘()’ 中表达式 '[]' 大表达式 '{}'

    什么是正则表达式:用来在一段不定字符.不定长度.具有简单规律的字符串中进行字符匹配的按照一定结构书写的表达式 什么事子表达式:'()' 代表一个子表达式,将其中的内容视为一个整体进行处理. 子表达式是 ...

  5. 子节点含有表单元素的div元素的blur事件

    1.div元素的blur事件 blur事件一般在表单元素如input元素才是存在的,对div.span等元素时无效的,但是可以给div元素加上tabindex属性,也可以让div等元素有焦点,所以bl ...

  6. jquery查找父窗体id_JavaScript_jQuery子窗体取得父窗体元素的方法,本文实例讲述了jQuery子窗体取 - phpStudy...

    jQuery子窗体取得父窗体元素的方法 本文实例讲述了jQuery子窗体取得父窗体元素的方法.分享给大家供大家参考.具体如下: $("#父窗口元素ID",window.parent ...

  7. 关于子业之间相互取得元素或者方法

    1.跳转是将页面name带过去 例子: url:"login.jsp?windowName="+window.name; 传递参数到子页面 ,使得子页面能够通过名字返回数据 2.获 ...

  8. 李涓子 | 机器智能加速器:大数据环境下知识工程的机遇和挑战

    本文转载自公众号:数据派THU. 导读:知识图谱已经成为推动人工智能发展的核心驱动力之一.本文选自清华大学计算机科学与技术系教授.清华-青岛数据科学研究院科技大数据研究中心主任李涓子老师于2017年1 ...

  9. 川大计算机专业导师冯子亮,问问川大计算机研究生招收的小专业有哪些

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 304计算机学院(028-85468665│ │ │ │ │ │ ) │ │ │ │ │ │077400☆计算机科学与技术 │ │170 │ │ │ │0 ...

  10. iframe子页面获取父页面元素,或父页面获取iframe子页面的元素

    用JS或jquery访问页面内的iframe,兼容IE/FF 注意:框架内的页面是不能跨域的! js 在父窗口中获取iframe中的元素 格式:window.frames["iframe的n ...

最新文章

  1. html 语言 gif 动画,动效篇(1)--从简单CSS3动画片段代码,到生成gif动图~
  2. 太赞!639 页《深度学习:Deep Learning》硬核课程 PPT 下载
  3. 湖南科技学院计算机科学与技术分数,湖南科技学院计算机科学与技术专业2016年在河南理科高考录取最低分数线...
  4. 改进AI/ML部署的5种方法
  5. dropout+Batch Normalization理解
  6. c++ fmt 库安装和使用示例、clion配置
  7. 【Java】统计随机抽出两个小于等于N的互异正整数的频率
  8. Hadoop组件启停命令和服务链接汇总
  9. Java并发编程笔记—基础知识—实用案例
  10. 计算机参观企业心得,走进联想 感悟联想——北航MBA参观联想集团总部
  11. linux修改管理员密码后保存,各类unix和linux管理员密码丢失解决方法
  12. Android一键反编译工具 jadx
  13. 移动安全初探:窃取微信聊天记录、Hacking Android with Metasploit
  14. MAC怎样显示隐藏文件
  15. 计算机网络:小明在家打开一个网址过程细致版(DNS缓存、DNS查询、TCP/IP协议、ARP协议、HTML渲染)
  16. 极限求解--泰勒公式理解
  17. 【人工智能AI】禅与计算机程序设计艺术:文心一言 vs ChatGPT对比:文心一言当然不仅仅只是“问答对话”那么简单,背后是 “人工智能的全栈技术体系”!
  18. 关于for循环遍历列表的几个用法--python
  19. 使用pre-signed URLs通过浏览器上传 无中间件前端直传 minio
  20. java派生类属例子_辨析之派生类属和相关类属

热门文章

  1. 使用fastcgi_cache加速你的Nginx网站
  2. 在线编辑fckeditor3
  3. Http Status Code (http 状态号)
  4. HNUCM 1325:fps游戏
  5. C程序设计--结构体(结构体和函数之间的参数使用)
  6. python调用c++动态库_python调用c++开发的动态库
  7. 中常用的数据结构_代码面试需要知道的8种数据结构(附面试题及答案链接)
  8. 字符串替换(NYOJ)
  9. 高速信号传输约翰逊 pdf_?高速滑环生产加工问题的具体分析
  10. 【CF1324E】Sleeping Schedule(dp)