網教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;  
}  



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章