【牛客网-每日一题3.25】tokitsukaze and Soldier
【题目链接】:传送门
【讲解】:传送门
【题解】
1、如果我们确定团队的大小Size,我们可以选择Size名士兵(其s>=Size)
2、根据(1)对士兵进行s从大到小排序
3、我们要做的是:控制团的大小S,同时确保val最大化,
所以我们对排序完的士兵依次添加,当s<Size时,依次弹出最小值。利用最小堆,维护区间中的最值问题。
1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long ll ; 8 const int N = 1e6 + 10 ; 9 typedef struct Node{ 10 int s,v; 11 //s size , v value 12 }Node; 13 Node a[N] ; 14 15 bool cmp( Node u , Node v ){ 16 return u.s > v.s ; 17 } 18 19 int main() 20 { 21 int n ; 22 //输入后排序,以s从小到大 23 scanf("%d",&n); 24 for( int i = 1 ; i <= n ; i++ ){ 25 scanf("%d%d",&a[i].v,&a[i].s); 26 } 27 sort( a + 1 , a + 1 + n , cmp ); 28 29 int Sz = 0 ; 30 priority_queue< int , vector<int> , greater<int> > Q ; 31 ll ans = 0 , sum = 0 ; 32 for( int i = 1 ; i <= n ; i++ ){ 33 Q.push( a[i].v ); 34 sum += a[i].v ; 35 Sz ++ ; 36 while( Sz > a[i].s ){ 37 //printf(" %d , %lld\n",i,sum) ; 38 sum -= (int) Q.top() ; 39 Q.pop(); 40 Sz -- ; 41 } 42 ans = max( ans , sum ); 43 } 44 printf("%lld\n",ans); 45 return 0 ; 46 }