Educational Codeforces Round 62 (Rated for Div. 2) C. Playlist 贪心+优先队列

You have a playlist consisting of nn songs. The ii-th song is characterized by two numbers titi and bibi — its length and beauty respectively. The pleasure of listening to set of songs is equal to the total length of the songs in the set multiplied by the minimum beauty among them. For example, the pleasure of listening to a set of 33 songs having lengths [5,7,4][5,7,4] and beauty values [11,14,6][11,14,6] is equal to (5+7+4)⋅6=96(5+7+4)⋅6=96.You need to choose at most kk songs from your playlist, so the pleasure of listening to the set of these songs them is maximum possible.c++

Input
The first line contains two integers nn and kk (1≤k≤n≤3⋅1051≤k≤n≤3⋅105) – the number of songs in the playlist and the maximum number of songs you can choose, respectively.Each of the next nn lines contains two integers titi and bibi (1≤ti,bi≤1061≤ti,bi≤106) — the length and beauty of ii-th song.

Output
Print one integer — the maximum pleasure you can get.

Examples


input

4 3
4 7
15 1
3 6
6 8

output

78



input

5 3
12 31
112 4
100 100
13 55
55 50

output

10000



Note
In the first test case we can choose songs 1,3,41,3,4, so the total pleasure is (4+3+6)⋅6=78(4+3+6)⋅6=78.In the second test case we can choose song 33. The total pleasure will be equal to 100⋅100=10000100⋅100=10000.

昨天晚上写的,没想出来,头疼得连水题都写得特别慢,今天确定又得掉分了。数据结构

题目大意是给咱们n首歌曲,每首歌都有两个特征:美丽值和时长。让咱们选择至多k首歌组成一个播放列表,让这个播放列表的“舒坦值”最高,舒坦值的计算是,集合中全部歌曲的播放时长之和,乘以集合中歌曲的最小价值。spa

pleasure=max(timesum)*min(beauty in song set)

考场上我没想明白,后来看了几份代码,才发现是这么作:code

  1. 就是对全部的歌曲按美丽值升序排列。
  2. 建立一个小根堆,存时长相对大的歌曲。初始为空。
  3. 从全部排序过的歌曲中,从后向前遍历,加入小根堆中,并记录当前堆中的歌曲时间和sum。若是小根堆size小于k则能够接着加,若是大于k,则pop栈顶元素,而且sum-对应值。对每次尝试加入操做,都计算sum*beauty[i],就是当前歌曲美丽值和sum的乘积,这个值得最大值就是咱们的答案。

因为咱们已经按美丽值对歌曲升序排序,因此从后向前遍历,美丽值确定在降低,也就是说每次遍历,都取到了能取到的最大beauty值,而且因为小根堆的存在,因此咱们的时长sum值也老是当前状况下的最大值,则遍历完整个歌曲集合后,获得的结果就是答案。排序

下面是代码。ip

#include <bits/stdc++.h>
#define N 300010
using namespace std;
typedef pair<int,int> p;
typedef long long ll;
p song[N];
ll n,k,sum,ans;void attemptAdd(int c);priority_queue<int,vector<int>,greater<int> > q;int main()  {
    cin>>n>>k;
    for (int i=0;i<n;i++)
        cin>>song[i].second>>song[i].first;
    sort(song,song+n);
    for (int i=n-1;i>=0;i--)    {
        attemptAdd(song[i].second);
        ans=max(ans,sum*song[i].first);
    }
    cout<<ans<<endl;
    return 0;}

void attemptAdd(int c)   {
    q.push(c);
    sum+=c;
    if ((int)q.size()>k)    {
        sum-=q.top();
        q.pop();
    }}

单从本题看,有这样的一个结论:ans=变化值*最值,则能够对最值排序,让每次取最优,而后对变化值用数据结构维护,也每次取最优,则结果就是最优值。ci

相关文章
相关标签/搜索