Chri_K

楼间跳跃

50分

#include<bits/stdc++.h>
#define val first
#define high second
using namespace std;
const int M = 1000000;
int n,m;
priority_queue <pair<int,int> > que;//降序排列 
int h[M + 5],v[M + 5];
int sum[M + 5];
int main()
{
    cin >> n >> m;
    for(int i = 1;i <= n;i ++)
    {
        cin >> h[i] >> v[i];
        sum[i] = sum[i - 1] + v[i];//求下前缀和,因为每走到下一楼是可以直接取一个,就相当于走到哪个楼,就可以直接取经过的地方的宝藏
    }
    int t1 = 0;
    int ans;
    int maxn = 0;
    for(int k = 1;k <= n;k ++)
    {
        int time = m - t1;//求出剩下还可以取多少
        for(int i = 1;i <= k;i ++)
            que.push(make_pair(v[i],h[i] - 1));//存入
        ans = sum[k];
        while(time > 0 && (!que.empty()))//如果优队不为空 就一直取最大的值
        {
            pair<int,int> a = que.top();
            que.pop();
            if(time < a.high)
            {
                ans += a.val * time;
                time = 0;
            }
            else
            {
                ans += a.val * a.high;
                time -= a.high;
            }
        }
        t1 ++;
        if(ans > maxn) maxn = ans;//更新
        while(!que.empty())
            que.pop();
    }
    cout << maxn;
    return 0;
}

100分

#include<bits/stdc++.h>
#define val first
#define high second
#define ll long long
using namespace std;
const int M = 1000000;
ll h[M + 5],v[M + 5];
ll n,m;
priority_queue <pair<ll,ll>,vector<pair<ll,ll> >,greater<pair<ll,ll> > > que;//所有的数据都要开long long
int main()
{
    cin >> n >> m;
    for(int i = 1;i <= n;i ++)
    {
        cin >> h[i] >> v[i];
        h[i] --;//第一个是不用花时间的
    }
    ll sum = 0;
    long long ans = 0;
    long long maxn = 0;
    for(int k = 1;k <= n;k ++)
    {
        ans += v[k];
        if(sum + h[k] <= m)//如果没取满 就直接加上
        {
            sum += h[k];
            ans += h[k] * v[k];
            que.push(make_pair(v[k],h[k]));
        }
        else
        {
            pair<ll,ll> a;
            a = que.top();
            while(a.val < v[k] && (!que.empty()))//如果比最小的要大,也要分两种,一种是可以全部丢掉,另一种是要留着一些,加上h[k]刚好是m
            {
                if(sum + h[k] - a.high >= m)
                {
                    que.pop();
                    ans = ans - a.high * a.val;
                    sum -= a.high;
                }
                else
                {
                    que.pop();
                    int mid = sum + h[k] - m;
                    ans = ans - mid * a.val;
                    a.high -= mid;
                    sum -= mid;
                    que.push(a);
                    break;
                }
                a = que.top();
            }
            int mark = m - sum;//求出k的填充值
            pair<ll,ll> q;
            q.val = v[k];
            q.high = mark;
            if(q.high)
            {
                que.push(q);
                ans = ans + q.val * q.high;
                sum = m;
            }
        }
        if(ans > maxn) 
            maxn = ans;//更新
        m --;//到下一层,自由支配的选择的空间要变小,因为到下一层就相当于花 1 单位的时间取下一层的某一个值
    }
    cout << maxn;
    return 0;
}

 

posted on 2020-10-22 14:09  Chri_K  阅读(12)  评论(0编辑  收藏  举报