博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第k小子集
阅读量:5914 次
发布时间:2019-06-19

本文共 1164 字,大约阅读时间需要 3 分钟。

有n个数,共有2^n个子集,一个子集的值看做其所有数的和。
求这2^n个子集中第K小的子集。
n<=35。

 

meet in the middle + 二分判定

注意在双指针逼近时,相等的数带来的影响

#include
#include
#define N 262500using namespace std;int n,k,a[40],half,note;int tmp1[N],sum1,tmp2[N],sum2;int l,r,mid,ans;void dfs(int now,int tot,int *tmp,int &sum){ if(now>note) { tmp[++sum]=tot; return; } dfs(now+1,tot,tmp,sum); dfs(now+1,tot+a[now],tmp,sum);} bool check(){ int j=sum2,cnt1,cnt2,tot=0,last=0; for(int i=1;i<=sum1;i++) { while(j && tmp1[i]+tmp2[j]>mid) j--; if(!j) break; cnt1=cnt2=1; while(i
1 && tmp2[j-1]==tmp2[j]) j--,cnt2++; tot+=last; if(tot>=k) return false; last=cnt1*cnt2; } return true;}int main(){ scanf("%d%d",&n,&k); half=n>>1; for(int i=1;i<=n;i++) scanf("%d",&a[i]),r+=a[i]; note=half; dfs(1,0,tmp1,sum1); note=n; dfs(half+1,0,tmp2,sum2); sort(tmp1+1,tmp1+sum1+1); sort(tmp2+1,tmp2+sum2+1); while(l<=r) { mid=l+r>>1; if(check()) ans=mid,l=mid+1; else r=mid-1; } printf("%d",ans);}

 

转载于:https://www.cnblogs.com/TheRoadToTheGold/p/7270429.html

你可能感兴趣的文章
Linux之通配符
查看>>
ios中摄像头和图片调用
查看>>
Content Provider 基础 之URI
查看>>
管理表空间和数据文件——使用OMF方式管理表空间
查看>>
ios获取安装的app
查看>>
Visual Studio 2012出现“无法访问T-SQL组件和安装了不兼容伯 DacFx版本”的解决办法...
查看>>
第一个版本
查看>>
JSTL I18N 格式标签库 使用之二_____读取消息资源
查看>>
九、Null在Java中的精确表示
查看>>
php 连接 mssql sql2008
查看>>
所谓技术团队绩效
查看>>
读书笔记-深入理解JVM虚拟机-1.OOM初探
查看>>
Yii CDbCriteria 常用方法
查看>>
libgc 加 .make 在 vc6 vs2008 中的编译方法
查看>>
用条件变量实现事件等待器的正确与错误做法
查看>>
软件度量都该度个啥?(5)——被吹得最多的六西格玛
查看>>
Maven教程初级篇02:pom.xml配置初步
查看>>
JavaScript基础系列--打败this
查看>>
如何开启MySQL慢查询日志
查看>>
用 Go 来了解一下 Redis 通讯协议
查看>>