uva 10891 Game of Sum(区间dp)
题目大意:有n个数字排成一条直线,然后有两个小伙伴来玩游戏, 每个小伙伴每次可以从两端(左或右)中的任意一端取走一个或若干个数(获得价值为取走数之和), 但是他取走的方式一定要让他在游戏结束时价值尽量的高,最头疼的是两个小伙伴都很聪明,所以每一轮两人都将按照对自己最有利的方法去取数字,请你算一下在游戏结束时,先取数的人价值与后取数人价值之差(不要求绝对值)。
解题思路:这道题目想了一晚上,死憋着不看题解, 结果写出的代码有点渣,dpx[i][j]表示在当前第i个数到第j个数中先取数的人可以达到的最高价值, dpy[i][j]为后取者最高可以达到的最高值。每次根据传入的参数flag判断是该谁去石子, 通过引用返回最优解。
注意:数字可以为负数,所以标记的时候要注意, 我是重新开了个数组vis.
- #include <stdio.h>
- #include <string.h>
- const int N = 105;
- const int MAX = -0x3f3f3f3f;
- int n, num[N], sum[N], dpx[N][N], dpy[N][N], vis[N][N];
- void search(int a, int b, int& x, int& y, int flag) {
- int &A = dpx[a][b], &B = dpy[a][b];
- if (a + 1 == b)
- A = num[b], B = 0;
- if (!vis[a][b]) {
- int s, f;
- A = sum[b] - sum[a], B = 0;
- for (int i = a + 1; i < b; i++) {
- search(i, b, s, f, !flag);
- if (flag && f + sum[i] - sum[a] > A)
- A = f + sum[i] - sum[a], B = s;
- else if (!flag && s + sum[i] - sum[a] > A)
- A = s + sum[i] - sum[a], B = f;
- search(a, i, s, f, !flag);
- if (flag && f + sum[b] - sum[i] > A)
- A = f + sum[b] - sum[i], B = s;
- else if (!flag && s + sum[b] - sum[i] > A)
- A = s + sum[b] - sum[i], B = f;
- }
- }
- vis[a][b] = 1;
- if (flag)
- x = B, y = A;
- else
- x = A, y = B;
- }
- void solve() {
- int s, f;
- memset(dpx, MAX, sizeof(dpx));
- memset(dpy, MAX, sizeof(dpy));
- memset(vis, 0, sizeof(vis));
- search(0, n, s, f, 0);
- printf("%d\n", s - f);
- }
- int main() {
- while (scanf("%d", &n) == 1 && n) {
- // Read;
- memset(num, 0, sizeof(num));
- memset(sum, 0, sizeof(sum));
- for (int i = 1; i <= n; i++) {
- scanf("%d", &num[i]);
- sum[i] = sum[i - 1] + num[i];
- }
- solve();
- }
- return 0;
- }
参考别人的题解,写了下面这个代码,因为两个小伙伴都是按照对自己最有利的方式取数字,那可以看成是一个过程,而确定区间a 到 b的最优解之后, 用sum(a, b) - 最优解就是后取数字的小伙伴可以取到的价值(只有两个人在玩,不是1拿就是2拿), 后取小伙伴的价值坑定是要尽量小自己拿到的才有可能越大。
- #include <stdio.h>
- #include <string.h>
- const int N = 105;
- const int MAX = 1 << 30;
- int max(int a, int b) { return a > b ? a : b; }
- int min(int a, int b) { return a < b ? a : b; }
- int n, dp[N][N], vis[N][N], num[N], sum[N];
- void read() {
- memset(dp, 0, sizeof(dp));
- memset(vis, 0, sizeof(vis));
- sum[0] = 0;
- for (int i = 1; i <= n; i++) {
- scanf("%d", &num[i]);
- sum[i] = sum[i - 1] + num[i];
- }
- }
- int solve(int a, int b) {
- if (a >= b) return 0;
- if (vis[a][b]) return dp[a][b];
- int ans = -MAX, cnt = b - a;
- vis[a][b] = 1;
- for (int i = 1; i <= cnt; i++)
- ans = max(ans, sum[b] - sum[a] - min(solve(a + i, b), solve(a, b - i)));
- dp[a][b] = ans;
- return ans;
- }
- int main() {
- while (scanf("%d", &n), n) {
- read();
- printf("%d\n", solve(0, n) * 2 - sum[n]);
- }
- return 0;
- }
uva 10891 Game of Sum(区间dp)的更多相关文章
- UVA - 10891 Game of Sum 区间DP
题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19461 Game of sum Description This ...
- UVA 10891 Game of Sum(DP)
This is a two player game. Initially there are n integer numbers in an array and players A and B get ...
- 09_Sum游戏(UVa 10891 Game of Sum)
问题来源:刘汝佳<算法竞赛入门经典--训练指南> P67 例题28: 问题描述:有一个长度为n的整数序列,两个游戏者A和B轮流取数,A先取,每次可以从左端或者右端取一个或多个数,但不能两端 ...
- UVa 10891 - Game of Sum 动态规划,博弈 难度: 0
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
- uva 10003 Cutting Sticks 【区间dp】
题目:uva 10003 Cutting Sticks 题意:给出一根长度 l 的木棍,要截断从某些点,然后截断的花费是当前木棍的长度,求总的最小花费? 分析:典型的区间dp,事实上和石子归并是一样的 ...
- UVA 10891 Game of Sum(区间DP(记忆化搜索))
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- UVA - 10891 Game of Sum (区间dp)
题意:AB两人分别拿一列n个数字,只能从左端或右端拿,不能同时从两端拿,可拿一个或多个,问在两人尽可能多拿的情况下,A最多比B多拿多少. 分析: 1.枚举先手拿的分界线,要么从左端拿,要么从右端拿,比 ...
- 28.uva 10891 Game of Sum 记忆化dp
这题和上次的通化邀请赛的那题一样,而且还是简化版本... 那题的题解 请戳这里 ... #include<cstdio> #include<algorithm> #i ...
- UVa 10891 Game of Sum (DP)
题意:给定一个长度为n的整数序列,两个人轮流从左端或者右端拿数,A先取,问最后A的得分-B的得分的结果. 析:dp[i][j] 表示序列 i~j 时先手得分的最大值,然后两种决策,要么从左端拿,要么从 ...
随机推荐
- Linux中ssh的免密码登陆
原理: Hadoop的各个节点要实时的进行各种通信的,ssh就是能让各个节点免密码的相互访问相互通信. 操作步骤: 这里用的加密方式是非对称的加密方式,具体的操作是: <1>执行命令ssh ...
- Struts学习之集成Ajax
转自:http://blog.csdn.net/hanxuemin12345/article/details/38782213 一,引题 1,Json数据格式简介 JSON是脱离语言的理想的数据交换格 ...
- codeforces 609F. Frogs and mosquitoes 二分+线段树
题目链接 F. Frogs and mosquitoes time limit per test 2 seconds memory limit per test 512 megabytes input ...
- 【转】AC算法详解
原文转自:http://blog.csdn.net/joylnwang/article/details/6793192 AC算法是Alfred V.Aho(<编译原理>(龙书)的作者),和 ...
- 转: js中的getYear()函数的问题(推荐用 getFullYear())
用了JS的getYear()方法,但是发现生成的代码竟然有108(本应该是2008),发现这是firefox下的问题. 然后google了一下,发 现原来是这样的:var today = new da ...
- 导入jsp
<%@ page contentType="text/html;charset=UTF-8" %><%@ page isELIgnored="false ...
- Trie三兄弟——标准Trie、压缩Trie、后缀Trie
1.Trie导引 Trie树是一种基于树的数据结构,又称单词查找树.前缀树,字典树,是一种哈希树的变种.应用于字符串的统计与排序,经常被搜索引擎系统用于文本词频统计.用于存储字符串以便支持快速模式匹配 ...
- Apache RewriteCond RewriteRule 入门和Laravel去掉index.php
Ci删除index.php办法: 创建.htaccess 文件放到网站的根目录下,文件中的内容如下: RewriteEngine onRewriteCond %{REQUEST_FILENAM ...
- 使用 IIS Manager 对 Windows Azure 网站进行远程管理
最近,我们为客户新增了使用 Windows自带的 IIS管理控制台管理 Azure网站的功能.IIS Manager支持 HTTP over SSL,提供到您的 Windows Azure 网站 ...
- vs2013 linq to mysql
安装文件 1.下载安装文件 2.创建项目 3.创建mysql数据连接 4.新建ADO.NET数据模型 项目实现代码 using (WorkerContainer db = new WorkerCont ...