随笔分类 - 数学之博弈论#题解
1
摘要:http://poj.org/problem?id=3710 (说实话对于Tarjan算法在搞图论的时候就没搞太懂,以后得找时间深入了解) (以下有关无向图删边游戏的资料来自论文贾志豪《组合游戏略述——浅谈SG游戏的若干拓展及变形》) 首先,对于无向图的删边游戏有如下定理性质: 1.(Fushion Principle定理)我们可对无向图做如下改动:将图中的任意一个偶环缩成一个新点,任意一个...
阅读全文
摘要:http://poj.org/problem?id=2599 #include #include #include #include #include using namespace std; int n,k,pos; vector g[1005]; bool flag[1005]; int dfs(int k) { for(int i=0;i<g[k].size();i++) ...
阅读全文
摘要:http://poj.org/problem?id=2425 #include #include #include #include using namespace std; struct node { int to,next; }e[10000010]; int head[1010],Ecou; int sg[1010]; void add_edge(int u,int v) { ...
阅读全文
摘要:http://poj.org/problem?id=2068 #include #include #include #include using namespace std; int dp[25][(1<<13)+5];//dp[i][j]表示轮到第i个人取时,剩j个石头 int n,s,m[25]; int DFS(int pos,int remain) { if(dp[pos][r...
阅读全文
摘要:http://poj.org/problem?id=1678 #include #include #include #include using namespace std; const int INF=10e8; int n,a,b,p[10005],dp[10005]; int dfs(int x) { if(dp[x]!=-INF) return dp[x]; ...
阅读全文
摘要:(Nim积相关资料来自论文曹钦翔《从“k倍动态减法游戏”出发探究一类组合游戏问题》) 关于Nim积计算的两个函数流程: 代码实现如下: int m[2][2]={0,0,0,1}; int Nim_Multi_Power(int x,int y) { if(x=(1=(1 #include using namespace std; in...
阅读全文
摘要:题目链接 #include #include #include using namespace std; int sg[2010]; int get_sg(int n) { if(n<0) return 0; if(sg[n]!=-1) return sg[n]; bool vis[2010]; //莫名其妙! //vis[]数组要声明在函数里,如果放...
阅读全文
摘要:题目链接 #include #include #include using namespace std; int sg[205][205]; bool vis[300]; int get_sg(int n,int m) { if(sg[n][m]!=-1) return sg[n][m]; for(int i=2;i<=n-i;i++) vis...
阅读全文
摘要:题目链接 #include #include using namespace std; int main() { int n; while(scanf("%d",&n)&&n) {//alice先把环破坏,变成链,然后bob只要在链中间取1或2个 //连续的coins,让链变成左右对称的两条,bob就必胜 if(n==1||n==2) ...
阅读全文
摘要:题目链接 #include #include using namespace std; typedef long long ll; int main() { ll n; while(~scanf("%I64d",&n)) {//其实算是 贪心了吧 //先手想赢,他会x2,这样子才能尽量避免让后手赢 //后手想赢,他就会x9,只有乘最大的,他胜算才最大 ...
阅读全文
摘要:题目链接 #include #include using namespace std; int main() { int n,k[1005]; int sum,cnt; while(scanf("%d",&n)&&n) { sum=0,cnt=0; for(int i=1;i=(sum^k[i])) //sum^k[i]要加括号()...
阅读全文
摘要:题目链接 #include #include #include using namespace std; int a[1005]; int main() { int n; while(~scanf("%d",&n)) {//要后者胜,只要s=0,那么n=(m+1)*r,输出最小的m即可 int len=0; bool flag=0; ...
阅读全文
摘要:POJ 1704 题目链接 关于阶梯博弈有如下定理: 将所有奇数阶梯看作n堆石头,做Nim,将石头从奇数堆移动到偶数堆看作取走石头,同样地,异或值不为0(利己态)时,先手必胜。 定理证明看此博:http://blog.csdn.net/kk303/article/details/6692506 以下是POJ 1704的AC代码: //棋子只能往左走(最左有界线),可以走任意多格(>=1) /...
阅读全文
摘要:这道题没说a b最大多少,所以要声明为long long型,不然会WA! 道理很简单,(默认a>=b)a和b只有以下三种关系: 1.a%b==0 :这种关系下,可能是a/b为整数,也可能是a和b都为0,不论哪种,都会是先者胜; 2.a2*b :这种关系下,下一步总能变成(a,a%b)和(a,a%b+b)两种状态,而这两种状态又与第2种状态(a #include using ...
阅读全文
摘要:传送门 以下复制自此处:http://www.xuebuyuan.com/2028180.html 博弈论题目可以用寻找必败状态的方法解决。 第一个必败状态是2001.11.04。由此可以推出其他任何时间的状态。对于除2001.11.04外的其他任何时间,present状态是由能移动到的下两个next状态决定的(当然有些时间只有一个next状态),比如1924.12.19的...
阅读全文
摘要:传送门 //有n堆,AB轮流从n堆的一堆中移任意个,可以扔掉,也可以移给其他堆中的一堆 //最先移完的胜 //如果n堆中两两堆数目相等,那肯定是B胜 //但只要有非两两相同的,如xyz,A先, //A可以从最多的那堆(z)移y-x个到x堆,yyp,最终移走p的一定是A #include #include #include #include using namespace std; int mai...
阅读全文
摘要:传送门 #include #include #include using namespace std; int main() { int n; while(~scanf("%d",&n)) { int a,res=0; int c=0,g=0; for(int i=0;i=2) c++; else i...
阅读全文
摘要:传送门 #include #include #include using namespace std; int main() { int t; scanf("%d",&t); while(t--) { int n,a,res=0; int c=0,g=0;//¹Âµ¥¶Ñ¡¢³äÔ£¶Ñ scanf("%d",&n)...
阅读全文
摘要:传送门 #include #include #include #include using namespace std; int main() { int n; while(~scanf("%d",&n)) { int a,res=0; for(int i=0;i<n;i++) { scanf("%d...
阅读全文
摘要:传送门 #include #include #include #include #include using namespace std; int main() { int a,b; while(~scanf("%d%d",&a,&b)) { int ok=1; if(a>b) swap(a,b); int k=b-a; ...
阅读全文
1

浙公网安备 33010602011771号