This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end of the array but cannot take from both ends at a time. He can take as many consecutive numbers as he wants during his time. The game ends when all numbers are taken from the array by the players. The point of each player is calculated by the summation of the numbers, which he has taken. Each player tries to achieve more points from other. If both players play optimally and player A starts the game then how much more point can player A get than player B?

Input

The input consists of a number of cases. Each case starts with a line specifying the integer n (0 < n ≤100), the number of elements in the array. After that, nnumbers are given for the game. Input is terminated by a line where n=0.

Output

For each test case, print a number, which represents the maximum difference that the first player obtained after playing this game optimally.

题目大意:给n个数,两个人轮流取数,可以从左往右或从右往左取任意多个。两个人都希望自己的取得的数的总和尽量大,都采取最优策略,问第一个人能比第二个人取得的数多多少。

思路:很容易可以想到一个$O(n^3)$的DP,用dp[i][j]代表只剩下a[i..j]的数,先手可以取得的最大值,此时后手取得的最大值为sum[i..j] - dp[i][j]。

那么状态转移方程为:dp[i][j] = max(sum[i..j], sum[i..j] - min(dp[i+1][j], dp[i+2][j]……), sum[i..j] - min(dp[i][j - 1], dp[i, j - 2])。

输出结果为2 * dp[1][n] - sum[1..n]。

代码(0.026S):

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6.  
  7. const int MAXN = ;
  8.  
  9. int dp[MAXN][MAXN];
  10. int a[MAXN], sum[MAXN];
  11. int n;
  12.  
  13. int main() {
  14. while(scanf("%d", &n) != EOF && n) {
  15. for(int i = ; i <= n; ++i) scanf("%d", a + i);
  16. for(int i = ; i <= n; ++i) sum[i] = sum[i - ] + a[i];
  17. for(int k = ; k < n; ++k) {
  18. for(int i = ; i + k <= n; ++i) {
  19. int j = i + k;
  20. dp[i][j] = sum[j] - sum[i - ];
  21. for(int p = i + ; p <= j; ++p) dp[i][j] = max(dp[i][j], sum[j] - sum[i - ] - dp[p][j]);
  22. for(int p = j - ; p >= i; --p) dp[i][j] = max(dp[i][j], sum[j] - sum[i - ] - dp[i][p]);
  23. }
  24. }
  25. printf("%d\n", * dp[][n] - sum[n]);
  26. }
  27. }

这个DP还有优化的余地,观察状态转移方程可以发现,dp[i][j]使用了min(dp[i+1][j], dp[i+2][j]……),而dp[i+1][j]=min(dp[i+2][j], dp[i+3][j]……),有重复的部分。

于是我们可以用l[i][j]记录max(dp[i][j], dp[i+1][j], dp[i+2][j]……),即从左往右取的后手最小值,则sum[i..j] - min(dp[i+1][j], dp[i+2][j]……)可以写成sum[i..j]-l[i+1][j]。每次更新l[i][j] = min(dp[i][j], l[i+1][j])。

同理用r[i][j]记录从右往左取的后手最小值。

至此DP优化至$O(n^2)$。

代码(0.015S):

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6.  
  7. const int MAXN = ;
  8.  
  9. int dp[MAXN][MAXN];
  10. int l[MAXN][MAXN], r[MAXN][MAXN];
  11. int a[MAXN], sum[MAXN];
  12. int n;
  13.  
  14. int main() {
  15. while(scanf("%d", &n) != EOF && n) {
  16. for(int i = ; i <= n; ++i) scanf("%d", a + i);
  17. for(int i = ; i <= n; ++i) sum[i] = sum[i - ] + a[i];
  18. for(int k = ; k < n; ++k) {
  19. for(int i = ; i + k <= n; ++i) {
  20. int j = i + k;
  21. l[i][j] = r[i][j] = dp[i][j] = sum[j] - sum[i - ];
  22. if(i != j) {
  23. dp[i][j] = max(dp[i][j], sum[j] - sum[i - ] - l[i + ][j]);
  24. dp[i][j] = max(dp[i][j], sum[j] - sum[i - ] - r[i][j - ]);
  25. l[i][j] = min(dp[i][j], l[i + ][j]);
  26. r[i][j] = min(dp[i][j], r[i][j - ]);
  27. }
  28. }
  29. }
  30. printf("%d\n", * dp[][n] - sum[n]);
  31. }
  32. }

UVA 10891 Game of Sum(DP)的更多相关文章

  1. uva 10891 Game of Sum(区间dp)

    题目连接:10891 - Game of Sum 题目大意:有n个数字排成一条直线,然后有两个小伙伴来玩游戏, 每个小伙伴每次可以从两端(左或右)中的任意一端取走一个或若干个数(获得价值为取走数之和) ...

  2. UVA 10891 Game of Sum(区间DP(记忆化搜索))

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  3. UVA - 10891 Game of Sum (区间dp)

    题意:AB两人分别拿一列n个数字,只能从左端或右端拿,不能同时从两端拿,可拿一个或多个,问在两人尽可能多拿的情况下,A最多比B多拿多少. 分析: 1.枚举先手拿的分界线,要么从左端拿,要么从右端拿,比 ...

  4. Max Sum (dp)

    Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. F ...

  5. URAL 1146 Maximum Sum(DP)

    Given a 2-dimensional array of positive and negative integers, find the sub-rectangle with the large ...

  6. UVA - 10891 Game of Sum 区间DP

    题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19461 Game of sum Description This ...

  7. HDU 1003 Max Sum(DP)

    点我看题目 题意 : 就是让你从一个数列中找连续的数字要求他们的和最大. 思路 : 往前加然后再判断一下就行. #include <iostream> #include<stdio. ...

  8. 【UVa】Partitioning by Palindromes(dp)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=27&page=sh ...

  9. 【noi 2.6_1481】Maximum sum(DP)

    题意:求不重叠的2段连续和的最大值. 状态定义f[i]为必选a[i]的最大连续和,mxu[i],mxv[i]分别为前缀和后缀的最大连续和. 注意:初始化f[]为0,而max值为-INF.要看好数据范围 ...

随机推荐

  1. MySQL安装图解教程

    安装文件存放路径:不能有中文和空格! 校验 1 安装MySQL 2 校验MySQL 登录MySQL:mysql -uroot -p123 退出MySQL:exit | quit 查看数据库:show ...

  2. angularJS自定义指令scope代替link

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  3. Linux的常用基本命令

    Linux的常用基本命令. 首先启动Linux.启动完毕后需要进行用户的登录,选择登陆的用户不同自然权限也不一样,其中“系统管理员”拥有最高权限. 在启动Linux后屏幕出现如下界面显示: …… Re ...

  4. 常用jQuery代码02

    一.each函数拿到每个元素的宽度 setTimeout(function () { $(".sticker_list img").each(function () { var W ...

  5. Java实验五报告——TCP传输及加解密

    一.实验内容 1.运行教材上TCP代码,结对进行,一人服务器,一人客户端: 2.利用加解密代码包,编译运行代码,一人加密,一人解密: 3.集成代码,一人加密后通过TCP发送: 注:加密使用AES或者D ...

  6. (leetcode)Reverse Linked List 脑子已经僵住

    Reverse a singly linked list. 参考http://www.2cto.com/kf/201110/106607.html 方法1: 讲每个节点的指针指向前面就可以. /** ...

  7. 解决libc.so.6: version `GLIBC_2.14' not found问题

    今天centos新机器上运行项目的时候出现题目所示的错误,搜索后发现是底层glibc 版本太低导致. strings /lib64/libc.so.6 |grep GLIBC_ 使用上面的命令发现 g ...

  8. undefined reference to `switch_dev_unregister'

    编译内核时,使用默认的配置进行编译.出现错误:undefined reference to switch_dev_unregister',undefined reference toswitch_se ...

  9. imx6 lvds 代码分析

    查看imx6 kernel中lvds设备和驱动的初始化过程. 相关文档: arm/arm/mach-mx6/board-mx6q_sabresd.c kernel/drivers/video/mxc/ ...

  10. offset/client/scroll一些总结

    offset/client/scroll一些总结 1.offset 首先offset共有五个值 1.offsetParent 2.offsetTop 3.offsetLeft 4.offsetWidt ...