牛客 tokitsukaze and Soldier ###K ###K //K

题目链接:https://ac.nowcoder.com/acm/problem/50439

思路: 选和不选的问题,首先想的是dp 但是看时间复杂度就能排除,受限制于s[i] 所以并不知道怎么取才是最优的

那么考虑固定下s[i]后再来做, 还必须边固定边维护下来 最大值  所以 将s 从大到小排序 然后枚举 再用优先队列维护一个小根堆,每次超过范围的时候扔掉堆顶  其实就是枚举当前是s[i]限制下的最大值 但不可能每次都

具体去算 所以要一累计下来 每一次枚举都要o(1)得到

每个数最多入队出队一次     时间复杂度o(nlogn) 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define pb push_back
 6 const int maxn=2e5+10;
 7 const int mod=998244353;
 8 struct ac
 9 {
10     ll v,s;
11 };
12 ac a[maxn];
13 
14 bool cmp(ac a,ac b)
15 {
16     return a.s>b.s;
17 }
18 
19 int main()
20 {
21     ios::sync_with_stdio(false);
22     cin.tie(0);
23     int n;
24     cin>>n;
25     for(int i=1;i<=n;i++)
26     {
27         cin>>a[i].v>>a[i].s;
28     }
29     sort(a+1,a+1+n,cmp);
30     ll ans=0;
31     ll sum=0;
32     ll min1=1e9;
33     priority_queue<pair<int,int>>q;
34     for(int i=1;i<=n;i++)
35     {
36         sum+=a[i].v;
37         min1=min(min1,a[i].s);
38         q.push({-a[i].v,a[i].v});
39         while((int)q.size()>min1)
40         {
41             sum-=q.top().second;
42             q.pop();
43         }
44         ans=max(ans,sum);
45 
46     }
47     cout<<ans<<'\n';
48 
49 
50 
51 
52 
53 
54 
55 }
View Code

 

posted @ 2020-07-15 11:20  canwinfor  阅读(157)  评论(0)    收藏  举报