楼间跳跃
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; }