101234G Dreamoon and NightMarket 求第K大集合
阿新 • • 發佈:2018-12-22
1.題意:給你n種物品的價值,讓你求這些物品組合的第k大的集合的值(集合內放的是物品種類,不得重複,但價值可以重複)
2.分析:歸結為一類經典問題,求第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個即可
3.程式碼:
#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; }