题意:给你n种物品的价值,让你求这些物品组合的第k大的集合的值(集合内放的是物品种类,不得重复,但价值可以重复)、
思路:这是一类经典的问题求集合元素所有组合中第K大的值。
具体的步骤如下:
(1)首先将储存元素的数组排序;
(2)假设当前组合中最后一个元素的下标为 i , 考虑为以i为最后一个元素的全排列都举过了。那么从当前组合(sum, i)到下一个最小组合有两种可能:减去本身再加上后一个,直接加上后一个。
这个图可以说明我们思路的正确性,也类似于DFS思想不过变得更为简洁。(图是盗的嘿嘿)
下面直接给出AC代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=2*1e5+100;
const double eps=1e-6;
typedef long long ll;
typedef pair<ll,int> P;
priority_queue<P,vector<P>,greater<P> > que;
int n,k;
int a[maxn];
void solve()
{
que.push(make_pair(a[0],0));
int cnt=0;
while(true)
{
int idx=que.top().second;
ll sum=que.top().first;
if(idx<n-1)
{
que.push(make_pair(sum+a[idx+1],idx+1));
que.push(make_pair(sum-a[idx]+a[idx+1],idx+1));
}
que.pop();
cnt++;
if(cnt==k)
{
printf("%lld",sum);
break;
}
}
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
sort(a,a+n);
solve();
return 0;
}