题目链接
题目大意
有一个长度为n的数组,问你这个数组里所有的非空子集的和的第k大是多少
解题思路
二分子集的和,判断是否满足条件,去枚举每一个子集,判断不大于mid的有多少个。
当开始的时候,我的cnt枚举到结束的时候才++,其实有新元素加入的时候就可以++了,这样比较省时。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=2e5+5;
long long a[N];
int cnt,n,k,vis[N];
void dfs(int x,long long sum,long long mid)
{
if(cnt>=k)
return ;
if(x>n)
return ;
if(sum+a[x]<=mid)
{
cnt++;
dfs(x+1,sum+a[x],mid);
dfs(x+1,sum,mid);
}
}
int main()
{
scanf("%d %d",&n,&k);
long long l=1,r=0;
for(int i=1; i<=n; i++)
{
scanf("%lld",&a[i]);
r+=a[i];
}
sort(a+1,a+1+n);
long long ans=0;
while(l<=r)
{
long long mid=(l+r)/2;
//memset(vis,0,sizeof(vis));
cnt=0;
dfs(1,0,mid);
// printf("%lld %lld %d\n",l,r,cnt);
if(cnt>=k)
{
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
printf("%d\n",ans);
return 0;
}