目录
一. 问题描述
Problem Description
给你n种物品的价值,让你求这些物品组合的第k大集合的值。
Hint
集合内放的是物品种类,不得重复,但价值可以重复
二. 题解代码
归结为一类经典问题,求第K大集合。其求解步骤如下:
(1)将数组排序
(2)假设当前组合中最后一个元素的下标为 i , 考虑为以i为最后一个元素的全排列都举过了;那么从当前组合(sum, i)到下一个最小组合有两种可能(若 i < n):
- sum + value[i+1] , i+1
- sum - value[ i ] + value[i + 1] , i+1
(3)图示说明
注意:不重不漏,优先队列存储,输出第k个即可
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,int> P;
const int maxn = 100000 + 7;
int num[2*maxn];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i = 0;i<n;i++){
scanf("%d",&num[i]);
}
sort(num,num+n);
priority_queue<P,vector<P> , greater<P> >que;
que.push(P(num[0],0));
int len = 0;
while(!que.empty()){
P p = que.top();
que.pop();
if(++len==k){
printf("%lld\n",p.first);
return 0;
}
if(p.second + 1 < n){
que.push(P(p.first + num[p.second + 1] , p.second + 1));
que.push(P(p.first - num[p.second] + num[p.second + 1],p.second + 1));
}
}
return 0;
}