zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    [JavaScript]JS由来
    [HTML5]HTML表单(Forms)
    Linux 配置SSH 无密钥登陆
    Spring Boot 的 application.properties
    Spring Boot 全局异常捕获
    Linux hostname设置,静态ip设置,hostname与静态ip相互映射
    Hadoop 集群的三种方式
    网站列表
    Hadoop -- 概念
    shell 编程
  • 原文地址:https://www.cnblogs.com/mchcylh/p/4837342.html
Copyright © 2011-2022 走看看