标签:一个人 for NPU cas center number class put div
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 2334 | Accepted: 916 |
Description
Input
Output
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
标签:一个人 for NPU cas center number class put div
原文地址:https://www.cnblogs.com/zZh-Brim/p/9160717.html