牛客 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 }

浙公网安备 33010602011771号