zoukankan      html  css  js  c++  java
  • lightoj 1031(dp)

    题意:一排数字两个人轮流从两边拿,都采用最优策略。问先手最多能拿到多少个。

    思路:dp[i][j]表示先手在i-j中最多能拿到的数字之和,然后从小到大枚举区间

    状态转移:

    dp[j][i+j] = max(dp[j][i+j], sum[k-1] - sum[j-1] - dp[k][i+j]);
    dp[j][i+j] = max(dp[j][i+j], sum[i+j] - sum[k] - dp[j][k]);

    代码如下:

     1 /**************************************************
     2  * Author     : xiaohao Z
     3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
     4  * Last modified : 2014-05-06 11:34
     5  * Filename     : L_1031.cpp
     6  * Description     : 
     7  * ************************************************/
     8  #include <iostream>
     9 #include <cstdio>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <cmath>
    13 #include <algorithm>
    14 #include <queue>
    15 #include <stack>
    16 #include <vector>
    17 #include <set>
    18 #include <map>
    19 #define MP(a, b) make_pair(a, b)
    20 #define PB(a) push_back(a)
    21 
    22 using namespace std;
    23 typedef long long ll;
    24 typedef pair<int, int> pii;
    25 typedef pair<unsigned int,unsigned int> puu;
    26 typedef pair<int, double> pid;
    27 typedef pair<ll, int> pli;
    28 typedef pair<int, ll> pil;
    29 
    30 const int INF = 0x3f3f3f3f;
    31 const double eps = 1E-6;
    32 const int LEN = 101;
    33 int n, dp[LEN][LEN], num[LEN], sum[LEN];
    34 
    35 int main()
    36 {
    37     freopen("in.txt", "r", stdin);
    38 
    39     int T, kase = 1;
    40     cin >> T;
    41     while(T--){
    42         cin >> n;
    43         for(int i=1; i<=n; i++)
    44             cin >> num[i];
    45         sum[0] = 0;
    46         for(int i=1; i<=n; i++) sum[i] = sum[i-1] + num[i];
    47         for(int i=0; i<n; i++){
    48             for(int j=1; j+i<=n; j++){
    49                 dp[j][i+j] = sum[i+j] - sum[j-1];
    50                 for(int k=j; k<=j+i; k++){
    51                     if(k!=j)
    52                         dp[j][i+j] = max(dp[j][i+j], sum[k-1] - sum[j-1] - dp[k][i+j]);
    53                     if(k!=i+j)
    54                         dp[j][i+j] = max(dp[j][i+j], sum[i+j] - sum[k] - dp[j][k]);
    55                 }
    56             }
    57         }
    58         cout << "Case " << kase++ << ": " << dp[1][n] << endl;
    59     }
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    [CF1038F]Wrap Around[AC自动机+dp]
    [LOJ#6198]谢特[后缀数组+trie+并查集]
    [CF986F]Oppa Funcan Style Remastered[exgcd+同余最短路]
    [CF587F]Duff is Mad[AC自动机+根号分治+分块]
    [CF995F]Cowmpany Cowmpensation[树形dp+拉格朗日插值]
    [CF917D]Stranger Trees[矩阵树定理+解线性方程组]
    [CF1007D]Ants[2-SAT+树剖+线段树优化建图]
    [CF1007B]Pave the Parallelepiped[组合计数+状态压缩]
    [CF1010E]Store[kd-tree]
    【JZOJ3598】【CQOI2014】数三角形
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3711279.html
Copyright © 2011-2022 走看看