zoukankan      html  css  js  c++  java
  • uva 10891 Game of Sum (DP水题)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1832

      博弈类的DP,通过枚举较短一段的最大得分推出较长一段的最大得分。转移方程是 dp[i][j] = sum[i][j] - min(dp[i][i], dp[i][i + 1], ... , dp[i][j - 1], dp[i + 1][j], dp[i + 2][j], ... ,dp[j][j])。

    O(n^3)算法:

    View Code
     1 #define REP(i, n) for (int i = 0; i < (n); i++)
     2 #define REP_1(i, n) for (int i = 1; i <= (n); i++)
     3 
     4 int dp[N][N], sum[N];
     5 
     6 int main() {
     7     int n;
     8     while (~scanf("%d", &n) && n) {
     9         sum[0] = 0;
    10         REP_1(i, n) {
    11             scanf("%d", &sum[i]);
    12             sum[i] += sum[i - 1];
    13         }
    14         _clr(dp);
    15         REP_1(d, n) {
    16             REP_1(i, n - d + 1) {
    17                 int j = i + d - 1, tmp = sum[j] - sum[i - 1];
    18                 dp[i][j] = tmp;
    19                 REP(l, d - 1) {
    20                     dp[i][j] = max(dp[i][j], tmp - dp[i][i + l]);
    21                     dp[i][j] = max(dp[i][j], tmp - dp[j - l][j]);
    22                 }
    23             }
    24         }
    25 //        printf("%d %d\n", dp[1][n], sum[n] - dp[1][n]);
    26         printf("%d\n", (dp[1][n] << 1) - sum[n]);
    27     }
    28     return 0;
    29 }

    在计算较短段的时候记录头尾的最小值,可以得到O(n^2)算法:

    View Code
     1 #define REP(i, n) for (int i = 0; i < (n); i++)
     2 #define REP_1(i, n) for (int i = 1; i <= (n); i++)
     3 
     4 int dp[N][N], sum[N], rec[2][N];
     5 
     6 int main() {
     7     int n;
     8     while (~scanf("%d", &n) && n) {
     9         sum[0] = 0;
    10         REP_1(i, n) {
    11             scanf("%d", &sum[i]);
    12             sum[i] += sum[i - 1];
    13         }
    14         _clr(dp);
    15         REP(i, 2) REP_1(j, n) rec[i][j] = inf;
    16         REP_1(d, n) {
    17             REP_1(i, n - d + 1) {
    18                 int j = i + d - 1, tmp = sum[j] - sum[i - 1];
    19                 dp[i][j] = max(tmp, max(tmp - rec[0][i], tmp - rec[1][j]));
    20                 rec[0][i] = min(dp[i][j], rec[0][i]);
    21                 rec[1][j] = min(dp[i][j], rec[1][j]);
    22             }
    23         }
    24 //        printf("%d %d\n", dp[1][n], sum[n] - dp[1][n]);
    25         printf("%d\n", (dp[1][n] << 1) - sum[n]);
    26     }
    27     return 0;
    28 }

    ——written by Lyon

  • 相关阅读:
    手写redux
    require.context
    webpack cdn加速
    spy-debugger安装、调试步骤
    MAC设置应用在127.0.0.1:80
    javascript数据结构——栈
    Immutable.js了解一下?
    自己搭建服务器.并返回结果
    vue-cli2与vue-cli3在一台电脑共存
    JavaScript点击事件-一个按钮触发另一个按钮
  • 原文地址:https://www.cnblogs.com/LyonLys/p/uva_10891_Lyon.html
Copyright © 2011-2022 走看看