zoukankan      html  css  js  c++  java
  • USACO 3.3 游戏

    https://www.luogu.org/problemnew/show/P2734

    是道好dp,加深了我对区间dp的理解

    一开始可以有思路:f[i][j]表示区间i-j内,先手的最大得分

    但是转移有困难,因为我在思考第二个人会怎么走

    实际上这是没有必要的,动态规划不考虑所有步的细节,而是从前一种状态转移,至于前一种如何,并不关心

    考虑到,当f[i][j]的人先手取完之后,剩下的就是第二个人,这是可以把他认为是先手

    那么第一个人可能取a[i]或a[j],那剩下的人取的就是f[i + 1][j]或者f[i][j - 1],那么区间i-j的和减第二个人的得分就是第一个人的得分

    时间:1.0h

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    inline int read()
    {
      int ans = 0,op = 1;
      char ch = getchar();
      while(ch < '0' || ch > '9')
        {
          if(ch == '-') op = -1;
          ch = getchar();
        }
      while(ch >= '0' && ch <= '9')
        {
          (ans *= 10) += ch - '0';
          ch = getchar();
        }
      return ans * op;
    }
    const int maxn = 105;
    int n;
    int sum[maxn],a[maxn];
    int f[maxn][maxn];
    /*int dp(int i,int j)
    {
      if(j < i) return 0;
      if(f[i][j]) return f[i][j];
      return f[i][j] = max(sum[j] - sum[i] - dp(i + 1,j),sum[j - 1] - sum[i - 1] - dp(i,j - 1));
      }*/              
    int main()
    {
      n = read();
      for(int i = 1;i <= n;i++)
        a[i] = read(),f[i][i] = a[i];
      for(int i = 1;i <= n;i++)
        sum[i] = sum[i - 1] + a[i];
      for(int i = n - 1;i >= 1;i--)
        for(int j = i + 1;j <= n;j++)
          f[i][j] = max(sum[j] - sum[i - 1] - f[i + 1][j],sum[j] - sum[i - 1] - f[i][j - 1]);
      printf("%d %d",f[1][n],sum[n] - f[1][n]);
    }
  • 相关阅读:
    uboot和内核分区的修改
    2440移植内核到uboot上,打印乱码
    启动新内核出现:No filesystem could mount root, tried: ext3 ext2 cramfs vfa
    启动新内核出现:Kernel panic
    移植最新版本3.4.2内核
    2017团体程序设计天梯赛大区赛 L3-3 球队“食物链”
    leetcode543 Diameter of Binary Tree
    CF599B Spongebob and Joke
    poj1930 Dead Fraction
    poj3040 Allowance
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/10048200.html
Copyright © 2011-2022 走看看