1. 程式人生 > >[POJ1678] I Love this Game! - 博弈,DP

[POJ1678] I Love this Game! - 博弈,DP

memory Go lin set 一個 pro nta first exactly

I Love this Game!
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 2334 Accepted: 916

Description

A traditional game is played between two players on a pool of n numbers (not necessarily distinguishing ones).

The first player will choose from the pool a number x1 lying in [a, b] (0 < a < b), which means a <= x1 <= b. Next the second player should choose a number y1 such that y1 - x1 lies in [a, b] (Attention! This implies y1 > x1 since a > 0). Then the first player should choose a number x2 such that x2 - y1 lies in [a, b]... The game ends when one of them cannot make a choice. Note that a player MUST NOT skip his turn.

A player‘s score is determined by the numbers he has chose, by the way:

player1score = x1 + x2 + ...
player2score = y1 + y2 + ...

If you are player1, what is the maximum score difference (player1score - player2score) you can get? It is assumed that player2 plays perfectly.

Input

The first line contains a single integer t (1 <= t <= 20) indicating the number of test cases. Then follow the t cases. Each case contains exactly two lines. The first line contains three integers, n, a, b (2 <= n <= 10000, 0 < a < b <= 100); the second line contains n integers, the numbers in the pool, any of which lies in [-9999, 9999].

Output

For each case, print the maximum score difference player1 can get. Note that it can be a negative, which means player1 cannot win if player2 plays perfectly.

Sample Input

3
6 1 2
1 3 -2 5 -3 6
2 1 2
-2 -1
2 1 2
1 0

Sample Output

-3
0
1



提交地址 : POJ



題解:

我太菜了想不到;
我們假設兩個人分別選了A,B,C,D,E,F;
那麽ans = A - B + C - D + E - F;
整理一下 ans = A - (B - (C - (D - (E - F))));
我們發現這是一堆子問題想到了遞歸;
如果先手選了A,那麽後手肯定要最大化(B - (C - (D - (E - F))),來使自己獲得最大收益;
同樣後手選擇了B之後,先手又要最大化(C - (D - (E - F))來滿足自己的最大利益;
這樣我們設f[i]表示從第i個物品開始,並且先手選第i個物品的最大值;
這樣每一步都滿足屬於自己的最大收益;
來一波記憶化搜索;
對了, 由題意可知a, b > 0, 所以先排個序, 因為每一個人都要從後面選擇數;



Code:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 #define inf 1e9
 7 
 8 int T;
 9 int n, a, b;
10 int num[10010];
11 int f[10010];
12 
13 inline int dp(int x)
14 {
15     if (f[x] != -1) return f[x];
16     int ans = -inf;
17     for (register int i = x + 1 ; i <= n ; i ++)
18     {
19         if (num[i] - num[x] >= a and num[i] - num[x] <= b)
20         {
21             ans = max(ans, dp(i));
22         }
23     }
24     return ans == -inf ? f[x] = num[x] : f[x] = num[x] - ans;
25 }
26 
27 inline int solve()
28 {
29     int ans = -inf;
30     for (register int i = 1 ; i <= n ; i ++)
31         if (num[i] >= a and num[i] <= b)
32             ans = max(ans, dp(i));
33             
34     return ans == -inf ? 0 : ans;
35 }
36 
37 int main()
38 {
39     cin >> T;
40     while (T--)
41     {
42         scanf("%d%d%d", &n, &a, &b);
43         for (register int i = 1 ; i <= n ; i ++) scanf("%d", &num[i]);
44         sort(num+1, num+1+n);
45         memset(f, -1, sizeof f);
46         printf("%d\n", solve());
47     }
48     return 0;
49 }


[POJ1678] I Love this Game! - 博弈,DP