[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 ...
随机推荐
- shell脚本的参数传递使用
1.params.sh源码如下 #!/bin/bash # author:daokr # url:www.daokr.com echo "Shell 传递参数实例!"; echo ...
- 洛谷 P1191 矩形 题解
P1191 矩形 题目描述 给出一个 \(n \times n\)的矩阵,矩阵中,有些格子被染成白色,有些格子被染成黑色,现要求矩阵中白色矩形的数量 输入格式 第一行,一个整数\(n\),表示矩形的大 ...
- 如何下载SlideShare的PPT:2种方法
SlideShare中有很多不错的PPT,有时候确实想收藏怎么办,通常有2种方法: 1.SWF档案的PPT A. 打开PPT首页,按ctrl+U打开源码B. 找到类似以下语法的语句: <meta ...
- 2440sd初始化(存储器控制器寄存器的设置)
#define mem_contrl 0x48000000 //13个寄存器的基地址(看做一个内存块)init_sdram: ldr r0, =mem_contrl / ...
- CODE FESTIVAL 2016 Grand Final 题解
传送门 越学觉得自己越蠢--这场除了\(A\)之外一道都不会-- \(A\) 贪心从左往右扫,能匹配就匹配就好了 //quming #include<bits/stdc++.h> #def ...
- (18)打鸡儿教你Vue.js
介绍一下怎么安装Vue.js vue.js Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性. Vue.js是一个渐进的,可逐步采用的Jav ...
- Pytest权威教程21-API参考-04-钩子(Hooks)
目录 钩子(Hooks) 引导时的Hook方法 初始化时的Hook方法 测试运行时的Hook方法 收集用例时的Hook方法 生成测试结果时的Hook方法 调试/交互Hook方法 返回: Pytest权 ...
- Codeforces Round #383 D
传送门 Description Arpa has a rooted tree (connected acyclic graph) consisting of n vertices. The verti ...
- docker中部署django项目~~Dockfile方式和compose方式
1. 背景: 本机win10上,后端django框架代码与前端vue框架代码联调通过. 2. 目的: 在centos7系统服务器上使用docker容器部署该项目. 3. 方案一:仅使用基 ...
- dump文件
https://blog.csdn.net/icandoit_2014/article/details/78739962 可以看出,此种方法只适用于程序崩溃但没有立即自行退出的情况.倘若程序故障后自行 ...