zoukankan      html  css  js  c++  java
  • 区间DP lightoj 1031

    在此游戏中任意时刻的状态都是原始序列的一段子序列故:

    定义d(i, j) : 表示原来序列的第i ~ j个元素组成的子序列,在双方都采取最优策略的情况下,先手得分的最大值、

    状态转移时,需要枚举从左边或者从右边取多少个。因此

    d(i, j) = sum[i, j] - min{d(i+1, j), d(i + 2, j).....d(j, j) , d(i, j-1), d(i, j-2),, ... , d(i, i), 0}

    其中sum[i, j] 是元素i 到j 的和。这里的0是取完所有的数, 有了它方程就不需要显式的边界条件了。

    答案是 d(1, n) - (sum[1, n] - d(1, n)) = 2*d(1, n) - sum[1, n]

               先手                       后手

    记忆话一下就可以了

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 #define MAXN 110
     7 #define inf  100000000
     8 
     9 int dp[MAXN][MAXN];
    10 int z[MAXN];
    11 int sum[MAXN];
    12 bool vis[MAXN][MAXN];
    13 
    14 
    15 int d(int a,int b)
    16 {
    17     if(vis[a][b])
    18         return dp[a][b];
    19     vis[a][b]=1;
    20     int m=0;
    21     int i;
    22     for(i=a+1;i<=b;i++)m=min(m,d(i,b));
    23     for(i=a;i<=b;i++)m=min(m,d(a,i));
    24     dp[a][b]=sum[b]-sum[a-1]-m;
    25     return dp[a][b];
    26 }
    27 int main()
    28 {
    29     int t,ca;
    30     scanf("%d",&t);
    31     ca=1;
    32 
    33     while(t--)
    34     {
    35         int n,i;
    36         scanf("%d",&n);
    37         memset(vis,0,sizeof(vis));
    38         memset(dp,0,sizeof(dp));
    39         for(i=1;i<=n;i++)
    40         {
    41             scanf("%d",&z[i]);
    42             sum[i]=sum[i-1]+z[i];
    43         }
    44 
    45         printf("Case %d: %d
    ",ca++,2*d(1,n)-sum[n]);
    46     }
    47     return 0;
    48 }
  • 相关阅读:
    树莓派安装aria2轻松下载小资源
    利用树莓派3搭建可以发射无线局域网的微型服务器
    Vue语法
    redis-cluster集群
    分布式锁
    Redis--消息队列
    设计模式---享元模式
    设计模式(单例模式+原型模式)+ c#的内存分配机制
    MVC的ActionFilter
    MVC异常处理的7大场景 + MVC的异常处理的过滤器 + 全局异常
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6075770.html
Copyright © 2011-2022 走看看