• 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

  • 相关阅读:
    jvm
    深度学习 机器学习
    中小规模机器学习的问题
    threading.Condition()
    实现 TensorFlow 架构的规模性和灵活性
    随机条件场
    使用TensorFlow Serving优化TensorFlow模型
    PDB、PD、PMP、RTB哪个更好?为品牌主解锁程序化购买的选择技巧
    bisecting k-means
    内核futex的BUG导致程序hang死问题排查
  • 原文地址:https://www.cnblogs.com/LyonLys/p/uva_10891_Lyon.html
Copyright © 2020-2023  润新知