SOJ 1176 Two Ends

题目大意:首先输入n(n ≤ 1000),n为偶数,接着输入n个整数,n个整数的和不超过1,000,000.两个人每次只能从两端取数,第一个人A可以用任意策略,第二个人B用贪心策略(左右数相等取左数)。求在保证第一个人取得的和最大的前提下,两人取数和之差的最大值。

解题思路:动态规划。突破口在于A能取两头的数,B只能取两头最大数(相同取左),而每次取完一个数,能取数的区间就会减少一个。对A来说,每次取数有两种选择,如果A知道在更少区间范围的最优和之差,则可以作出最优的选择。对B来说,每次只能用贪心选数,比较容易。

a[i] 表示第i位的数。(0 ≤ i < n)

m[i][j] 表示剩余为 i -> j 时的最优和之差。(0 ≤ i ≤ j < n)

当区间为奇数时(即(j-i+1) % 2 == 1),B选择数,用贪心的策略:

  若 a[i] >= a[j] , 则 m[i][j] = m[i+1][j] - a[i].

  若 a[i] < a[j] , 则 m[i][j] = m[i][j-1] - a[j].

当区间为偶数时(即(j-i+1) % 2 == 0),A选择数,枚举两端取数,选择最优和之差:

  m[i][j] = max(a[i] + m[i+1][j], a[j] + m[i][j-1]).

代码如下:

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int maxn = 1005;
 6 int m[maxn][maxn];    // m[i][j] 代表 剩余 i -> j 区间时的第一人最大获利
 7 // 若 区间为奇数 j - i + 1 是奇数,则让第二人根据贪心算法先选择
 8 // 若 区间为偶数 j - i + 1 是偶数,则让第一人根据最大利益先选择
 9 int a[maxn];
10 int n;
11 
12 void init(int n) {
13     for (int i = 0; i < n; i++) {
14         for (int j = 0; j < n; j++) {
15             m[i][j] = 0;
16         }
17     }
18 }
19 
20 int main() {
21     int t = 0;
22     while (cin >> n, n != 0) {
23         t++;
24         for (int i = 0; i < n; i++) {
25             cin >> a[i];
26         }
27 
28         init(n);    // 初始化矩阵
29 
30         for (int i = 1; i <= n; i++) {
31             for (int j = 0; j < n; j++) {
32                 int k = j + i - 1;
33                 if (k > n - 1) break;
34                 // j -> k 为区间左右端点
35                 if (i % 2 == 1) {    // 奇数区间,第二人先选择
36                     if (a[j] >= a[k]) {    // 左边端点较大或相等
37                         m[j][k] = m[j + 1][k] - a[j];
38                     } else {    // 左边端点较小
39                         m[j][k] = m[j][k - 1] - a[k];
40                     }
41                 } else {    // 偶数区间,第一人先选择
42                     m[j][k] = max(a[j]+m[j+1][k], a[k]+m[j][k-1]);
43                 }
44             }
45         }
46 
47         cout << "In game " << t << ", the greedy strategy might lose by as many as " << m[0][n-1] << " points." << endl;
48     }
49 
50     return 0;
51 }
原文地址:https://www.cnblogs.com/mchcylh/p/4837342.html