题目链接:http://poj.org/problem?id=1678
动态博弈。用dp[i]来表示如果先行者首先选择第i个数字的话能取得的最大差值。由于每次选择的数字一定比上一次选择的数字大,所以先对数组进行排序。然后对于每个数字,如果先行者首先选择这个数字的话,dp[i] 初始化的值为num[i].然后在num[i]之后的序列中,如果有符合条件的数字的话,那么选择dp值最大的那个数字。最后对所有的数字进行for loop,寻找符合条件的并且差值最大的数字。代码如下:
1 //============================================================================ 2 // Name : test.cpp 3 // Author : 4 // Version : 5 // Copyright : Your copyright notice 6 // Description : Hello World in C++, Ansi-style 7 //============================================================================ 8 9 #include <iostream> 10 #include <math.h> 11 #include <stdio.h> 12 #include <cstdio> 13 #include <algorithm> 14 #include <string.h> 15 #include <string> 16 #include <sstream> 17 #include <cstring> 18 #include <queue> 19 #include <vector> 20 #include <functional> 21 #include <cmath> 22 #include <set> 23 #define SCF(a) scanf("%d", &a) 24 #define IN(a) cin>>a 25 #define FOR(i, a, b) for(int i=a;i<b;i++) 26 #define Infinity 999999999 27 #define NInfinity -999999999 28 #define PI 3.14159265358979323846 29 typedef long long Int; 30 using namespace std; 31 32 int main() 33 { 34 int t; 35 int n, a, b; 36 SCF(t); 37 int num[10005]; 38 int dp[10005]; 39 while (t--) 40 { 41 SCF(n); 42 SCF(a); 43 SCF(b); 44 FOR(i, 0, n) 45 SCF(num[i]); 46 47 sort(num, num + n); 48 49 for (int i = n - 1; i >= 0; i--) 50 { 51 dp[i] = num[i]; 52 bool first = true; 53 int maxNum = 0; 54 for (int j = i + 1; j < n; j++) 55 { 56 int diff = num[j] - num[i]; 57 if (diff >= a && diff <= b) 58 { 59 if (first) 60 { 61 maxNum = dp[j]; 62 first = false; 63 } 64 else 65 maxNum = max(maxNum, dp[j]); 66 } 67 } 68 dp[i] = dp[i] - maxNum; 69 } 70 int maxAns = 0; 71 bool found = false; 72 for (int i = n - 1; i >= 0; i--) 73 { 74 if (num[i] >= a && num[i] <= b) 75 { 76 if (!found) 77 { 78 maxAns = dp[i]; 79 found = true; 80 } 81 else 82 { 83 if (dp[i] > maxAns) 84 maxAns = dp[i]; 85 } 86 } 87 } 88 printf("%d\n", maxAns); 89 } 90 return 0; 91 }