[Google] 9717 取数对弈
我写的Python代码:
class Solution(object):
def getNumberGame(self, n, nums):
m = len(nums)
dp = [[0] * m for j in xrange(m)]
for i in xrange(m):
dp[i][i] = nums[i] for i in reversed(xrange(0, n)):
for j in xrange(i + 1, m):
sum = self.getSum(i, j, nums)
dp[i][j] = sum - min(dp[i+1][j], dp[i][j-1]) total_sum = self.getSum(0, n - 1, nums) return dp[0][n-1], total_sum - dp[0][-1] def getSum(self, i, j, nums):
sum = 0
for k in xrange(i, j + 1):
sum += nums[k] return sum if __name__ == '__main__':
print Solution().getNumberGame(6, [4, 7, 2, 9, 5, 2])
转自: DustLeon
描述
取数对弈游戏问题: 取数游戏是一个 2 人对策游戏。游戏开始时将 n 个数在棋盘上从左到右排成一行。 甲乙双方轮流在这一行数的左右两端取数,直至全部取完 n 个数。每人所取得的数的总和为其得分值。 最后双方得分多者获胜。(游戏规定由甲方先取数。) 这里,甲乙双方都采用如下最优策略:
1)甲每次取都希望取到的这个数使自己得分最高
2)乙每次取都希望取到的这个数令甲的得分最低 请编程实现:在甲乙双方都采用最优策略的前提下,计算甲方先取数时双方的最后得分。
输入格式
对于每组输入数据,输入数据的第 1 行有 1 个正整数 n (1<=n<=100),表示有 n 个数在棋盘上从左到右排成一行。
接下来的 n 个数表示在棋盘上依次排列的 n 个数。
输出格式
在甲乙双方都采用最优策略的前提下,输出计算出的双方的最后得分。甲方得分在前,乙方得分在后。
输入样例
6
4 7 2 9 5 2
输出样例
18 11
Hint
注意:此题“贪心法”是不能保证总可行且最优的,因为你不能只“关注眼前”,而“不管以后”。 :) 1、前提和假设如下:
每次取数都只能从数列的头尾选择。甲乙双方都依最优策略来选择。(得分=所取的数之和)
sum(i,j):表示a[i]到a[j]的元素之和,即sum(i,j) = a[i]+...+a[j]
p[i][j]:表示从a[i]到a[j]时,甲方先取数并在甲乙双方都采用最优策略的前提下时,甲方的最终得分。 注意:这个“甲乙双方都采用最优策略的前提”,其实是甲乙双方都尽量使自己的得分最大。
对甲方是使自己得分最高这个动机好理解,对乙方而言,使得甲方得分最低为下步策略,由于总分是一定的,其实也就是使乙方自己得分最大。
因此,虽然有甲乙2个人对弈,但他们动机是一致的。 2、分析如下:
当甲方取a[i]时,p[i][j] = sum(i,j) - p[i+1][j];
当甲方取a[j]时,p[i][j] = sum(i,j) - p[i][j-1];
甲方会取这两种情况较大的作为自己的选择。即sum(i,j) - min( p[i+1][j], p[i][j-1] ) 3、递归关系如下:
1)当j=i, p[i][j] = a[i];
2)当j>i, p[i][j] = sum(i,j) - min( p[i+1][j], p[i][j-1] ) 4、题目所求为:
所求的甲方得分 = p[1][n]; 乙方得分 = sum - p[1][n] 5、例如:(左边界i,右边界j)
j=i 4 7 2 9 5 2
j=i+1 7 7 9 9 5
j=i+2 6 11 7 11
j=i+3 16 16 11
j=i+4 11 14
j=i+5 18
C++:
#include <iostream>
using namespace std; int p[101][101]; int sum(int i, int j) {
int sum_num = 0;
for(int r = i; r <= j; r ++)
sum_num += p[r][r];
return sum_num;
} int main()
{
int n;
int num[101];
cin >> n;
if(1 <= n && n <= 100) {
for(int i = 1; i <= n; i ++) {
cin >> num[i];
p[i][i] = num[i];
}
for(int j = 2; j <=n; j ++) {
for(int i =1; i <= n - j + 1; i ++) {
int r = j + i - 1;
p[i][r] = sum(i,r) - (p[i+1][r] < p[i][r-1] ? p[i+1][r] : p[i][r-1]);
}
}
cout << p[1][n] << " " << sum(1,n) - p[1][n];
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std; int main()
{
int n,a[101],sum=0,m[101][101];
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
memset(m,0,sizeof(m));
for(int i=0;i<n;i++)
m[i][i]=a[i];
for(int i=n-1;i>=0;i--)
{
for(int j=i+1;j<n;j++)
{
sum=0;
for(int k=i;k<=j;k++)
sum+=a[k];
m[i][j] = sum-min(m[i+1][j],m[i][j-1]);
}
}
sum=0;
for(int k=0;k<=n-1;k++)
sum+=a[k];
printf("%d %d",m[0][n-1],sum-m[0][n-1]);
}
类似题目:
[LeetCode] 486. Predict the Winner 预测赢家
[Google] 9717 取数对弈的更多相关文章
- 洛谷P1288 取数游戏II[博弈论]
题目描述 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流 ...
- 洛谷P1288 取数游戏II
题目描述 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流 ...
- 【博弈论】【P1288】取数游戏II
传送门 Description 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点 ...
- luoguP1288 取数游戏II [博弈论]
题目描述 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流 ...
- NOIP2007 矩阵取数游戏
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...
- NOIP2007矩阵取数[DP|高精度]
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...
- Vijos1451圆环取数[环形DP|区间DP]
背景 小K攒足了路费来到了教主所在的宫殿门前,但是当小K要进去的时候,却发现了要与教主守护者进行一个特殊的游戏,只有取到了最大值才能进去Orz教主…… 描述 守护者拿出被划分为n个格子的一个圆环,每个 ...
- codevs 1907 方格取数 3
Description 在一个有m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法. Input 第 ...
- HDU 1565&1569 方格取数系列(状压DP或者最大流)
方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
随机推荐
- Java【基础学习】之暴力求素数【用数组返回】
Java[基础学习]之暴力求素数[用数组返回] */ import java.util.*; public class Main{ public static void main(String[] a ...
- saltstack 在window下 发布 service 服务
saltstack 发布 service 服务 如果是注册的服务发布: salt -L '172.16.3.39' state.sls service.deploy 目录结构: /home/sal ...
- Connection: close
在http1.1中request和reponse header中都有可能出现一个connection头字段,此header的含义是当client和server通信时对于长链接如何进行处理. 在http ...
- 史上最全java pdf精品书籍整理
算法,多线程,spring,数据库,大数据,面试题等等.喜欢的小伙伴加群获取 QQ群号825199617 (非广告培训技术群,纯java知识交流,请自重)
- Nginx:fastcgi_param详解
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;#脚本文件请求的路径 fastcgi_param QUERY_STRI ...
- qt creator中常用快捷键
激活欢迎模式 Ctrl + 1 激活编辑模式 Ctrl + 2 激活调试模式 Ctrl + 3 激活项目模式 Ctrl + 4 激活帮助模式 Ctrl + 5 激活输出模式 Ctrl + 6 查找当前 ...
- Confluence 实现公司wiki【转】
Confluence是一个企业级的Wiki软件,可用于在企业.部门.团队内部进行信息共享和协同编辑一.安装过程1 安装并配置mysql [root@vm1 ~]# /etc/my.cnf charac ...
- Understanding glibc malloc
https://wooyun.js.org/drops/深入理解%20glibc%20malloc.html https://sploitfun.wordpress.com/2015/02/10/un ...
- flutter -------- 页面跳转和传值
在安卓原生开发中,页面跳转可以用Intent类来具体实现: Intent intent =new Intent(MainActivity.this,second.class); startActivi ...
- ISO/IEC 9899:2011 条款6.8.6——跳转语句
6.8.6 跳转语句 语法 1.jump-statement: goto identifier ; continue ; break ; return expressio ...