题意:
给定n和k;
给定n个数(可看做一个集合),求第k大非空子集。
题解:
首先将数组排序,把第一个数及下标放入优先队列中。
假设第i大集合的元素和为ans,那么下一个最小集合的元素和有两种可能:
假设有三个数,下标为0,1,2;那么所有子集合为:
附代码:
#include <set> #include <map> #include <cmath> #include <stack> #include <queue> #include <vector> #include <string> #include <cstdio> #include <cstring> #include <sstream> #include <iomanip> #include <iostream> #include <algorithm> #define clr(str,x) memset(str,x,sizeof(str)) #define FRER() freopen("in.txt","r",stdin); #define FREW() freopen("out.txt","w",stdout); #define MAX_INF 0x7fffffff #define INF 0x3f3f3f3f #define maxn 1000010 typedef unsigned long long int ll; using namespace std; typedef pair<int,int> P; int n,k; int a[maxn]; int main() { //FRER() //FREW() scanf("%d%d",&n,&k); for(int i=0; i<n; i++) scanf("%d",&a[i]); sort(a,a+n); priority_queue<P,vector<P>,greater<P> > q; q.push(make_pair(a[0],0)); int cnt=0,ans,id; while(1) { if(cnt==k) break; ans=q.top().first; id=q.top().second; q.pop(); if(id<n-1) { q.push(make_pair(ans-a[id]+a[id+1],id+1)); q.push(make_pair(ans+a[id+1],id+1)); } cnt++; } printf("%d\n",ans); return 0; }