hrbust 2319 Number Game

Number Game
Time Limit: 1000 MSMemory Limit: 100000 K
Total Submit: 71(13 users)Total Accepted: 18(11 users)Rating: Special Judge: No
Description

There are n items and two players, Kim and you. For each player and for each item, the value of the item for this player is known. Denote values of the i-th item for the first and the second player as ai and bi correspondingly.

Players take the items in turns. Kim starts the game. Kim is greedy: each turn, he chooses the item which has the maximal ai among the remaining items. If there are several such items, he can take any one of them. What is the maximal possible sum of values bi of items taken by the second player that he can guarantee regardless of the first player’s moves?

Input


The first line is an integer T, describes the number of tests. Then T tests.

Each case contains a single integer n, the number of items.

The second line contains n numbers, i-th is equal to ai, the value of the i-th item for Kim.

The third line contains n numbers, i-th is equal to bi, the value of the i-th item for the second player.


Output

Output a single number: the maximal sum of values bi of items taken by the second player that he can guarantee.

Sample Input
1
5
1 2 3 4 5
2 3 4 5 6
Sample Output
8
Hint

1 <= n <= 1000

ai and bi are integers from 1 to 10e9

题目大意:你和另一个人Kim在玩轮流一个游戏,对方先开始,每次从ai组成的数组里面选取剩余的最大的数,然后轮到你从bi组成的数组里选择,每次已经被选的下标为i的数字双方都不能再一次选择。让你编写程序算出你选择的数字的和最大可以是多少。

输入:第一行为T,代表一共T组数据,每组数据有n,代表双方都是n个数字

接下来两行是ai和bi。

输出:你选择的数字最大和。

分析:首先用一个结构体把ai,bi存下来,然后以ai的大小从大到小排序,ai相同的以bi从大到小排序。那么如果对对方最有利的,而对自己的最后结果最小的就是ai选择0,2,4,6……,bi选择剩下的。首先对方第一个选择的肯定是第0个ai,从第二个开始,到你选择了,先把你最坏的结果存进一个小顶堆,那么下次你遇到比堆顶大的元素,此时把堆顶的元素删除,加入这个元素,就按照这样的方法贪心,最后可以贪心得到最后结果为和最大的选择。


可能对我的这个分析不能看懂,我解释一下代码:

首先用一个优先队列代替小顶堆(优先队列优先是从大到小优先顺序,相当于一个大顶堆,然后用相反的数存进优先队列就相当于是小顶堆),首先在排序的时候回保证选择到最优于对方的选择而的结果,当i是技术时候轮到自己选择,那么第二个选的会是最大的不一定会选bi,因此当i为偶数的时候,如果bi大于当前最小的元素则说明前面的选择可以更换。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
struct stu{
    int a,b;
}num[1005];
priority_queue<int>que;
bool cmp(stu u,stu v){
    if(u.a!=v.a)
        return u.a>v.a;
    else
        return u.b>v.b;
}
int main(){
    int t;
    int i,j,k;
    int n;
    scanf("%d",&t);
    long long ans;
    while(t--){
        scanf("%d",&n);
        for(i=0;i<n;i++){
            scanf("%d",&num[i].a);
        }
        for(i=0;i<n;i++){
            scanf("%d",&num[i].b);
        }
        sort(num,num+n,cmp);
        for(i=1;i<n;i++){
            if(i&1){
                que.push(-num[i].b);
            }
            else if(num[i].b>-que.top()){
                que.pop();
                que.push(-num[i].b);
            }
        }
        ans=0;
        while(!que.empty()){
            ans-=que.top();
            que.pop();
        }
        printf("%lld\n",ans);
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值