“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 K
最近盛大的一款游戏传奇世界极其火爆。游戏玩家John,想购买游戏中的装备。已知游戏的商店里有n 件装备,第i 件装备具有属性值a i ,购买需要花费b i 个金币。John想去购买这些装备,但是账号中只有m 个金币,John是个很贪婪的家伙,他想购买尽可能多的装备。并且在保证购买到最多件装备的情况下,他还想让他所购买的装备当中拥有最小属性值的装备的属性值尽可能大。
输入测试组数T ,每组数据第一行输入整数n (1<=n<=100000 )和m (1<=m<=10 9 ), 接下来有n 行,第i 行有两个数a i , b i (1<=a i ,b i <=10000 ).
对于每组数据,输出两个数字,第一个数字代表John最多可以购买的装备数,第二个数代表在John购买最多件装备的前提下,所购买的装备当中拥有最小属性值的装备的最大属性值(输入数据保证至少可以购买一件装备)
复制
1 2 4 3 2 2 3
1 3
解法:
1 能够决定最大的购买数量
2 先用贪心保存原始的购买情况,再考虑做替换
3 替换必须 比保存的最小价值要大,且替换进去不会超预算
4 内部保存也要排序啦,用优先队列啦
1 #include<bits/stdc++.h> 2 #define N 123456 3 #define LL long long 4 using namespace std; 5 struct Node{ 6 int a; 7 int b; 8 bool operator<(const Node &node) const{ 9 if(a!=node.a) return a>node.a; 10 return b>node.b; 11 } 12 }node[N]; 13 bool Nodesort(Node x,Node y){ 14 if(x.b==y.b){ 15 return x.a>y.a; 16 } 17 return x.b<y.b; 18 } 19 int main(){ 20 int t; 21 scanf("%d",&t); 22 while(t--){ 23 int n,m; 24 scanf("%d%d",&n,&m); 25 priority_queue<Node>Qu; 26 for(int i=1;i<=n;i++){ 27 scanf("%d%d",&node[i].a,&node[i].b); 28 } 29 int ans=0; 30 sort(node+1,node+1+n,Nodesort); 31 int sum=0; 32 for(int i=1;i<=n;i++){ 33 sum+=node[i].b; 34 if(sum<=m){ 35 ans++; 36 Qu.push({node[i].a,node[i].b}); 37 }else{ 38 sum-=node[i].b; 39 break; 40 } 41 } 42 if(Qu.size()==0){ 43 printf("0 0\n"); 44 }else{ 45 for(int j=ans+1;j<=n;j++){ 46 Node it=Qu.top(); 47 // cout<<it.a<<" "<<it.b<<endl; 48 if(node[j].a>it.a&&sum-it.b+node[j].b<=m){ 49 sum-=it.b; 50 sum+=node[j].b; 51 Qu.pop(); 52 Qu.push({node[j].a,node[j].b}); 53 } 54 } 55 printf("%d %d\n",ans,Qu.top().a); 56 } 57 } 58 return 0; 59 }