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

相關文章
相關標籤/搜索