经典博弈
来源:互联网 发布:java date format 编辑:程序博客网 时间:2024/06/05 18:24
描述
有两个人玩游戏,给定一个最大可取代数maxChoosableInteger,两个人轮流从1~maxChoosableInteger中取一个数,取过的数不可再取,若其中一方取过以后,所有取过的数的和大于等于desiredTotal,那么这个人获胜。现在给maxChoosableInteger和desiredTotal,问先手是否必胜,假定游戏双方均采取最优策略。你可以假定给出的maxChoosableInteger不超过20,desiredTotal不超过300。
样例
输入:
maxChoosableInteger = 10
desiredTotal = 11
输出:
false
说明
无论先手怎么取数,先手都会输掉游戏。先手可以取到1到10中的任何一个。如果先手取1,那么后手可以取2到10中任何一个。后手如果取10,那么就可以赢得游戏。假如先手取其它的数,那么后手仍然能赢得游戏。
思路
明显的是,这个全排列问题不能用枚举法来做。1~n的前缀后就是1~n-1的和加上n,用记忆化搜索判断胜利情况。要么当前剩下的desiredTotal小于等于0,要么对于剩下的还未取得数,已经搜索过且是必胜的状态。假设这个状态没有搜索过,就进行判断这个状态,直到遇到判断过的状态或desiredTotal小于等于0。
代码
#include "stdafx.h"#include<iostream>#include<vector>#include<algorithm>using namespace std;class Solution {public: vector<int> dp; vector<bool> used; bool boyi(int maxChoosableInteger, int desiredTotal) { int sum = (1 + maxChoosableInteger)*maxChoosableInteger / 2; if (sum < desiredTotal) { return false; } if (desiredTotal <= maxChoosableInteger) { return true; } dp.resize(1 << maxChoosableInteger); fill(dp.begin(),dp.end(),-1); used.resize(maxChoosableInteger + 1); fill(used.begin(), used.end(), 0); return handler(desiredTotal); } bool handler(int desiredTotal) { if (desiredTotal <= 0) return false; int key = fmt(used); if (dp[key] == -1) { for (int i = 1; i < used.size(); i++) { if (!used[i]) { used[i] = true; if (!handler(desiredTotal - i)) { dp[key] = -1; used[i] = false; return true; } used[i] = false; } } dp[key] = 0; } return dp[key] == 1; } int fmt(vector<bool> & used) { int num = 0; for (int i = 1; i < used.size(); i++) { num <<= 1; if (used[i]) { num |= 1; } } return num; }};int main(){ int maxChoosableInteger, desiredTotal; cin >> maxChoosableInteger >> desiredTotal; Solution sol; bool result=sol.boyi(maxChoosableInteger, desiredTotal); if (result) { cout << "true" << endl; } else { cout << "false" << endl; } return 0;}
阅读全文
0 0
- 经典博弈
- 经典博弈!
- 经典博弈
- 经典博弈
- 几个经典的博弈
- 经典博弈(转)
- 几个经典的博弈
- 几个经典的博弈
- poj1067(经典博弈问题)
- 博弈经典例子
- 经典博弈a
- 三个经典的博弈问题
- 三个经典的博弈问题
- 三种经典博弈问题
- hdu 4664 Triangulation 经典博弈
- 三种经典博弈问题
- 三种经典的博弈问题
- 博弈问题及SG函数(经典)
- 【代码笔记】iOS-自定义loading(IanAlert)
- [转] Ubuntu 16.04 U盘安装图文教程
- 使用Python语言完成SVM实现分类
- Vue.js的几个简单属性方法
- JavaScript之类型判断
- 经典博弈
- Ubuntu PeaZip [最好的压缩解压缩软件]
- NPM小结
- xml格式原样输出到html或是jsp页面
- ajax上传图片
- 邵国际: C 语言对象化设计实例 —— 命令解析器
- hihocoder 1636 : Pangu and Stones(区间dp)
- iOS UILabel中图文混排
- 批量删除