一个简单的博弈问题 取球问题
2013-05-31 00:00
239 查看
/*
今盒子里有n个小球,A、B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断。
我们约定:
每个人从盒子中取出的球的数目必须是:1,3,7或者8个。
轮到某一方取球时不能弃权!
A先取球,然后双方交替取球,直到取完。
被迫拿到最后一个球的一方为负方(输方)
请编程确定出在双方都不判断失误的情况下,对于特定的初始球数,A是否能赢?
程序运行时,从标准输入获得数据,其格式如下:
先是一个整数n(n<100),表示接下来有n个整数。然后是n个整数,每个占一行(整数<10000),表示初始球数。
程序则输出n行,表示A的输赢情况(输为0,赢为1)。
例如,用户输入:
4
1
2
10
18
则程序应该输出:
0
1
1
0
*/
//思路如下
/*
如果我们从 10000 个球开始的话,有点困难,我们不清楚怎么取球能赢,我们想列举出所有可能情况,但这个几乎不可能。因为情况太多,数量应该是指数级别的。
//----都是假定A先取球,
我们降低难度,从最简单的子问题开始,我们设想 :
<1> 当只有 1 个球时,A只有 1 种取法( 1 ) 如果 A 先取球,不管 A 怎么取,A都必输。
==> 记下这个经验 --> 1 个球时,先取必输
<2> 当有 2 个球时, A只有 1 种取法( 1 ), A当前只能取 1 个球,B输了
==> 记下这个经验 --> 2 个球时, 先取必赢
<3> 当有 3 个球时, A有 2 种取法(1,3), A就会想 我如果取 1 个球,此时还剩 2 个球,
那么根据前两次经验中第二个经验,"只有两个球时,先取必赢", 所以我不能取 1 个球,
我如果取 3 个球,那么我又输了。
==> 记下这个经验 --> 3 个球时, 先取必输
<4> 当有 4 个球时, A有 2 种取法(1, 3), 同样A又会想,我如果取 1 个球,此时还剩 3 个球,
那么根据前三次经验中第三个经验, "先取必输",所以我就取 1 个球即可赢得比赛。
==> 记下这个经验 --> 4 个球时, 先取必赢
<5> 当有 5 个球时。。。。。
。
。
。
。
。
<n> 当有 n 个球时 。。。。。
通过不断迭代,得到这个第 n 个球时,就是我们要求得结果。
这就是动态规划过程,先将大问题划分成子问题,再从子问题开始着手,先解出子问题的解,从子问题解出发,
逐步加大问题,倒着追根溯源,找到我们要求解的问题为止。
注意:实际上动态规划时都是先能构造原问题与子问题之间的递归方程,按照递归方程列算法
*/
//代码如下,以模仿动态规划方式解答
今盒子里有n个小球,A、B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断。
我们约定:
每个人从盒子中取出的球的数目必须是:1,3,7或者8个。
轮到某一方取球时不能弃权!
A先取球,然后双方交替取球,直到取完。
被迫拿到最后一个球的一方为负方(输方)
请编程确定出在双方都不判断失误的情况下,对于特定的初始球数,A是否能赢?
程序运行时,从标准输入获得数据,其格式如下:
先是一个整数n(n<100),表示接下来有n个整数。然后是n个整数,每个占一行(整数<10000),表示初始球数。
程序则输出n行,表示A的输赢情况(输为0,赢为1)。
例如,用户输入:
4
1
2
10
18
则程序应该输出:
0
1
1
0
*/
//思路如下
/*
如果我们从 10000 个球开始的话,有点困难,我们不清楚怎么取球能赢,我们想列举出所有可能情况,但这个几乎不可能。因为情况太多,数量应该是指数级别的。
//----都是假定A先取球,
我们降低难度,从最简单的子问题开始,我们设想 :
<1> 当只有 1 个球时,A只有 1 种取法( 1 ) 如果 A 先取球,不管 A 怎么取,A都必输。
==> 记下这个经验 --> 1 个球时,先取必输
<2> 当有 2 个球时, A只有 1 种取法( 1 ), A当前只能取 1 个球,B输了
==> 记下这个经验 --> 2 个球时, 先取必赢
<3> 当有 3 个球时, A有 2 种取法(1,3), A就会想 我如果取 1 个球,此时还剩 2 个球,
那么根据前两次经验中第二个经验,"只有两个球时,先取必赢", 所以我不能取 1 个球,
我如果取 3 个球,那么我又输了。
==> 记下这个经验 --> 3 个球时, 先取必输
<4> 当有 4 个球时, A有 2 种取法(1, 3), 同样A又会想,我如果取 1 个球,此时还剩 3 个球,
那么根据前三次经验中第三个经验, "先取必输",所以我就取 1 个球即可赢得比赛。
==> 记下这个经验 --> 4 个球时, 先取必赢
<5> 当有 5 个球时。。。。。
。
。
。
。
。
<n> 当有 n 个球时 。。。。。
通过不断迭代,得到这个第 n 个球时,就是我们要求得结果。
这就是动态规划过程,先将大问题划分成子问题,再从子问题开始着手,先解出子问题的解,从子问题解出发,
逐步加大问题,倒着追根溯源,找到我们要求解的问题为止。
注意:实际上动态规划时都是先能构造原问题与子问题之间的递归方程,按照递归方程列算法
*/
//代码如下,以模仿动态规划方式解答
/* 文件名称: 取球 创建日期: 2013/3/11 */ #include <iostream> #include <vector> #include <algorithm> using namespace std; const a[4] = {1, 3, 7, 8}; bool serach1(vector<bool> v, int n) { int i; for (i = 0; i < 4; i++) { int k = n - a[i]; if (k == 0) return false; if (v[k] == false) return true; } return false; } void show(vector<b 3ff8 ool> v) { vector<bool>::iterator it; int k = 0; for (it = v.begin() + 1; it != v.end(); it++) { ++k; cout << k << "\t" << *it << "\n"; } cout << endl; } int main() { vector<bool> v; v.push_back(0);//废除 v.push_back(0);//1 v.push_back(1); v.push_back(0);//3 int i = 0; for (i = 4; i < 100; i++) { v.push_back(serach1(v, i)); } return 0; }
相关文章推荐
- Pro*C编程初步 + 栽在了一个非常简单的问题上
- 为复杂的问题找一个简单的答案
- sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)
- Dos 写的一个简单脚本 + 乱码问题
- 算法学习---一个博弈问题
- Ubuntu 10.04下安装OpenCV及编译一个简单例程(找不到头文件的问题:error: cv.h: No such file or directory )
- 一个关于MoveWindow,ScreenToClient,ClientToScreen,GetWindowRect,GetClientRect的简单问题
- 项目中一个简单SQL查询问题,已经解决了,留个纪念,非常感谢帮我的朋友们。
- 职责链模式和工厂模式混合求解一个简单的解密问题
- 数据结构中关于链表的一个简单问题
- 今天调试一个WebPart的简单程序出现的问题
- 今天在国外论坛上为别人解决一个简单问题
- 一个java简单问题
- 一个简单的循环移位问题
- 超简单的一个解决JAVA Enumeration问题的方案
- 关于2014年4月腾讯招实习生2面的一个简单问题
- leetcode 115. Distinct Subsequences 简单DP变形+一个必须要学会的DP问题
- 学习ejb并配置一个简单的helloEjb是遇到问题后总结的经验。
- 学习Java的第一步是安装好JDK,写一个Hello World, 其实JDK的学习没有那么简单,关于JDK有两个问题是很容易一直困扰Java程序员的地方:一个是CLASSPATH的问题,其实从原理上来说,是要搞清楚JRE的ClassLoader是如何加
- 问大佬们一个比较简单的问题