zoukankan      html  css  js  c++  java
  • Light OJ 1031: Easy Game 区间DP

    Easy Game

    题目链接:

    http://www.lightoj.com/volume_showproblem.php?problem=1031

    题意:

    给出一个含n个数的序列(n≤100),A和B每次能从这个序列的左端或右端取任意个数,这两个人很聪明,每次都会取对自己最优的情况(自己取得的数的和就是获得的分数,要使分数尽可能比对方的大),现在由A先开始取,求A的分数-B的分数的最大值。

    题解:

    有点博弈的感觉在里边,设dp[i,j]为区间[i,j]的最大值,则可以在[i,j]内取一个值k,使A先取k~j的所有值或者i~k的所有值,则dp[i][j]=max(dp[i][j],sum[j]-sum[k-1]-dp[i][k-1]),sum[j]-sum[k-1]-dp[i][k-1])),假设A先取了k~j的所有值 则此时答案为sum[k~j]-剩余区间中B可以得到的最优情况,同理得A先取i~k时的答案

    代码

    #include<stdio.h>
    #include<string.h>
    #define Type int
    #include<algorithm>
    using namespace std;
    const int N=101;
    Type dp[N][N],sum[N],a[N];
    Type mmax(Type x,Type y)
    {
      return x>y?x:y;
    }
    void clean()
    {
      for(int i=1;i<=100;++i)
      for(int j=1;j<=100;++j)
      dp[i][j]=(i>j?0:-999999999);
      sum[0]=0;
    }
    void solve()
    {
      int n,T,w=0;
      scanf("%d",&T);
      while(T--)
      {
        scanf("%d",&n);
        clean();
        for(int i=1;i<=n;++i)
        {
          scanf("%d",&a[i]);
          dp[i][i]=a[i];
          sum[i]=sum[i-1]+a[i];
        }
        for(int len=1;len<=n;++len)
        for(int i=1;i+len<=n;++i)
        {
          int j=i+len;
          for(int k=i;k<=j;++k)
          {
            dp[i][j]=mmax(dp[i][j],sum[k]-sum[i-1]-dp[k+1][j]);
            dp[i][j]=mmax(dp[i][j],sum[j]-sum[k-1]-dp[i][k-1]);
          }
        }
        printf("Case %d: %d ",++w,dp[1][n]);
      }
    }
    int main()
    {
      solve();
      return 0;
    }

     
  • 相关阅读:
    维度漫谈
    维度漫谈
    世界名曲
    世界名曲
    音乐的要素
    音乐的要素
    POJ 1300 欧拉通路&欧拉回路
    C库函数笔记
    malloc()参数为0的情况
    层层递进Struts1(三)之Struts组成
  • 原文地址:https://www.cnblogs.com/kiuhghcsc/p/5843599.html
Copyright © 2011-2022 走看看