zoukankan      html  css  js  c++  java
  • Light OJ 1031

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1031

    题目大意:两个选手,轮流可以从数组的任意一端取值, 每次可以去任意个但仅限在一端, 他们的得分分别是取得所有值的和。现在求这两个选手得分差值的最大值。

    解题思路:设dp[i][j]代表从i到j这个区间中,所能够得到的最大差值,只需要枚举其中i到j之间的一个数c,作为断电,那么最大值应该为max(sum[c]-sum[i-1]-dp[c+1][j], sum[j]-sum[c-1]-cou(i, c-1))。然后在更新这一个值就行了。

    代码如下:

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 107;
    int sum[N], dp[N][N];
    
    int cou(int i, int j)
    {
        if(i > j)
            return 0;
    
        if(dp[i][j] != INT_MAX)
            return dp[i][j];
    
        dp[i][j] = sum[j] - sum[i-1];
        for(int c=i; c<=j; ++ c)
        {
            dp[i][j] = max(dp[i][j], sum[c] - sum[i-1] - cou(c+1, j));
            dp[i][j] = max(dp[i][j], sum[j] - sum[c-1] - cou(i, c-1));
        }
    
        return dp[i][j];
    }
    
    void solve(int cases)
    {
        int n;
        scanf("%d", &n);
    
        for(int i=1; i<=n; ++ i)
            for(int j=1; j<=n; ++ j)
                dp[i][j] = INT_MAX;
    
        sum[0] = 0;
        for(int i=1; i<=n; ++ i)
        {
            scanf("%d", &sum[i]);
            dp[i][i] = sum[i];
            sum[i] += sum[i-1];
        }
        printf("Case %d: %d
    ", cases, cou(1, n));
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        for(int i=1; i<=t; ++ i)
            solve(i);
        return 0;
    }
    View Code
  • 相关阅读:
    Linux环境变量$PATH
    grep
    echo命令
    ip命令
    浅析Linux下的/etc/profile、/etc/bashrc、~/.bash_profile、~/.bashrc文件
    shell脚本4种执行方式
    /proc路径
    tr命令
    Linux命令cut
    前端论坛网站知识
  • 原文地址:https://www.cnblogs.com/aiterator/p/6241497.html
Copyright © 2011-2022 走看看