网教15. 谁更机智

题目描述

Alice: 上课好无聊啊!!!

Bob:那你想干嘛?

Alice:我们来玩游戏好伐?

Bob:好哇!咋玩?

Alice:我们写n个正整数,然后轮流拿数字,每次可以拿任意多个,每次的得分是这次拿的数字中的最小值,我们俩每次拿数都要让自己的得分与对方的得分差值最大化,我俩试着拿一拿看看最后我比你高多少分吧~

Bob:我拒绝,这明明O(瞬间)就知道答案了为啥还要玩儿

Alice:哇你好厉害,那我写n个数你说按刚才的策略,我先拿,最后比你高多少分,你要是答对了我就嘻嘻嘻

Bob:好,你等着,嘿嘿嘿

输入

第一行输入一个整数T表示用例组数,每组用例第一行输入一个整数n表示要拿的正整数个数,之后输入n个正整数ai

输出

每组用例输出一个整数占一行,表示两人按游戏策略拿完所有数字后Alice比Bob高多少分

数据范围

1<=T<=10,1<=n<=50000,1<=ai<=10^9

样例输入

1

3

1 3 1

样例输出

2

样例解释

Alice拿3,Bob拿1 1,最后两者得分差值是3-1=2

题解:

一开始没读懂题意,后来上网搜,竟然搜到了原题。。(KK's number)这个题的意思是每个人拿的时候目的都是自己减去对方的得分最大,题目没有说清楚。

至于怎么拿?要是我单独做的话我也没有什么思路。。可是我搜题意的时候竟然也搜到了题解。。用dp做,就是找只有前i个数时候的当前最优解,然后让i不断变大直到n为止即可。递推公式就是dp[i] = max(dp[i-1], a[i] - dp[i - 1]),三十行就能写完。

感觉dp真是一个黑科技啊。。。但是思考什么时候用dp,以及得到递推公式,是一个挺麻烦的过程。。。

AC代码:

#include<stdio.h>  
#include<string.h>  
#include<stdlib.h>  
int comp(const void*a,const void*b)  
{  
    return *(long long int*)a - *(long long int*)b;  
}  
long long int a[50005],dp[50005];  
long long max(long long a, long long b)  
{  
    return a > b ? a : b;  
}  
int main()  
{  
    int T;  
    scanf("%d", &T);  
    while (T--)  
    {  
        int n;  
        scanf("%d", &n);  
        int i;  
        for (i = 0; i < n; i++)  
            scanf("%lld", &a[i]);  
        qsort(a, n, sizeof(long long int), comp);  
        long long ans = 0;  
        dp[0] = 0;  
        for (i = 1; i < n; i++)  
            dp[i] = max(dp[i-1], a[i] - dp[i - 1]);  
        printf("%lld\n", dp[n - 1]);  
    }  
    return 0;  
}  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值