HDU4315 Climbing the Hill

题目链接:https://cn.vjudge.net/problem/HDU-4315

知识点:  博弈论

题目大意:

  \(Alice\) 和 \(Bob\) 轮流指挥 \(N\) 个人爬山,这 \(N\)个人在山顶下的不同层,国王是第 \(k\) 个人。山的每一层都最多只能容纳 \(1\) 个人(除了山顶),两个玩家每次都能指挥任意一个人向上爬任意层直到山顶,但不能让一个人越过另一个人。指挥国王爬到山顶上即可获胜。

解题思路:

  首先,如果国王是第一个人,先手必胜。

  如果 \(N\) 是偶数,关键局面为:对于所有合法的 \(i\),有第 \(2i\) 个人和第 \(2i-1\) 个人相邻。易知此时当国王是第偶数个人时后手必胜,因为无论先手怎么操作,后手都至少能维持住这个局面,或者取得胜利;当国王是第奇数个人时也是后手必胜,后手可以维持这个关键局面直到国王成为第 \(3\) 个人,并继续保持第 \(2i-1\) 和第 \(2i\) 相邻,先手接下来迟早会被迫将第一个人移到山顶,后手下一步将第二个人移到山顶的下一个位置,这是一个后手必胜的局面。现在游戏已经转换成一个 \(Nim\) 博弈,石子就是第 \(2i-1\) 和第 \(2i\) 个人之间的间隔。

  如果 \(N\) 是奇数,可以在第一个人前面再想象一个人,他在山顶的再上一层,当第一个人被放到山顶的时候,二者相邻,此时又转换成偶数个人的情况了。有一种特殊情况是当国王是第二个人的时候,那么想象出来的这个人就得放在山顶,当第一个人被放到山顶的下一层时二者即可相邻,因为先手如果将第一个人直接放到山顶,那么后手能直接取胜。

AC代码:

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4 const int maxn=1005;
 5 int pos[maxn];
 6 int main(){
 7     int N,k;
 8     while(scanf("%d%d",&N,&k)==2){
 9         for(int i=1;i<=N;i++)   scanf("%d",&pos[i]);
10         if(k==1){
11             printf("Alice\n");
12             continue;
13         }
14         if(N%2==0){
15             int sg=0;
16             for(int i=1;i<=N;i+=2)
17                 sg^=(pos[i+1]-pos[i]-1);
18             if(!sg) printf("Bob\n");
19             else    printf("Alice\n");
20         }
21         else{
22             int sg=pos[1];
23             if(k==2)    sg--;
24             for(int i=2;i<=N;i+=2)
25                 sg^=(pos[i+1]-pos[i]-1);
26             if(!sg) printf("Bob\n");
27             else    printf("Alice\n");
28         }
29     }
30     return 0;
31 }

原文地址:https://www.cnblogs.com/Blogggggg/p/9161870.html

时间: 2024-10-13 06:50:55

HDU4315 Climbing the Hill的相关文章

hdu4315 Climbing the Hill(阶梯博弈)

Climbing the Hill Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1218    Accepted Submission(s): 548 Problem Description Alice and Bob are playing a game called "Climbing the Hill". The g

HDU 4315 Climbing the Hill (尼姆博弈)

Climbing the Hill Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description Alice and Bob are playing a game called "Climbing the Hill". The game board consists of cells arranged vertically, as the

HDU 4315 Climbing the Hill [阶梯Nim]

传送门 题意: 和上题基本一样:山顶可以有多人,谁先把king放到山顶谁就胜 并不太明白 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; const int N=1005; inline int read(){ char

HDU 4315:Climbing the Hill(阶梯博弈)

http://acm.hdu.edu.cn/showproblem.php?pid=4315 题意:有n个人要往坐标为0的地方移动,他们分别有一个位置a[i],其中最靠近0的第k个人是king,移动的时候在后面的人不能越过前面的人,先把king送到0的人胜. 思路:阶梯博弈.把n个人两两配对,形成一个组,即a[i]和a[i+1]是一个组,a[i+2]和a[i+3]是一个组,把a[i]和a[i+1]的距离当成阶梯博弈中的奇数阶的值,a[i+1]和a[i+2]的距离当成偶数阶(不用考虑).首先k=1

博弈论类题目小结——转载

出处http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 首先当然要献上一些非常好的学习资料: 基础博弈的小结:http://blog.csdn.net/acm_cxlove/article/details/7854530 经典翻硬币游戏小结:http://blog.csdn.net/acm_cxlove/article/details/7854534 经典的删边游戏小结:http://blog.csdn.net/acm

MIP启发式算法:爬山算法 (Hill climbing)

本文主要记录和分享学习到的知识,算不上原创. *参考文献见链接. 本文讲述的是求解MIP问题的启发式算法中的爬山算法 (Hill climbing). 目录 前言 Hill climbing 的过程 Hill climbing 的伪代码 前言 爬山算法是以local search为核心框架的启发式算法中最简单的算法,当然,结果一般也不太好,因为爬山算法有一个很大的缺点:不能跳出局部解. 就像我们在local search那篇文中提到,以local search 为框架的启发式算法需要综合考虑到算

[虚拟机OA]Climb the hill 爬山

Jack was trying to go up the hill. He does not have any problem in climbing up or coming down the hill if the slope is consistently either increasing or decreasing. Areas where the slope is constant do not bother him in either situation. Given a list

70. Climbing Stairs

1. 问题描述 You are climbing a stair case. It takes n steps to reach to the top.Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?Tags:Dynamic Programming 2. 解题思路 简单分析之: f(1) = 1; f(2) = 2; f(3) = f(2) + f(1)

leetcode - Climbing Stairs

You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? //第一种解法 class Solution { public: int climbStairs(int n) { int ans[100] = {1,2}; for