hdoj 5996 - dingyeye loves stone(阶段博弈)

原题链接

dingyeye loves stone

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 54    Accepted Submission(s): 30


Problem Description
dingyeye loves play stone game with you.

dingyeye has an  n -point tree.The nodes are numbered from  0  to  n1 ,while the root is numbered  0 .Initially,there are  a[i]  stones on the  i -th node.The game is in turns.When one move,he can choose a node and move some(this number cannot be  0 ) of the stones on it to its father.One loses the game if he can't do anything when he moves.

You always move first.You want to know whether you can win the game if you play optimally.
 

Input
In the first line, there is an integer  T  indicating the number of test cases.

In each test case,the first line contains one integer  n  refers to the number of nodes.

The next line contains  n1  integers  fa[1]fa[n1] ,which describe the father of nodes  1n1 (node  0  is the root).It is guaranteed that  0fa[i]<i .

The next line contains  n  integers  a[0]a[n1] ,which describe the initial stones on each nodes.It is guaranteed that  0a[i]<134217728 .

1T100 , 1n100000 .

It is guaranteed that there is at most  7  test cases such that  n>100 .
 

Output
For each test case output one line.If you can win the game,print "win".Ohterwise,print "lose".
 

Sample Input
  
  
2 2 0 1000 1 4 0 1 0 2 3 3 3
 

Sample Output
  
  
win lose
 
某大牛思路:
  首先是对阶梯博弈的阐述...博弈在一列阶梯上进行...每个阶梯上放着自然数个点..两个人进行阶梯博弈...每一步则是将一个集体上的若干个点( >=1 )移到前面去..最后没有点可以移动的人输..


如这就是一个阶梯博弈的初始状态 2 1 3 2 4 ... 只能把后面的点往前面放...如何来分析这个问题呢...其实阶梯博弈经过转换可以变为Nim.. 把所有奇数阶梯看成N堆石子..做nim..把石子从奇数堆移动到偶数堆可以理解为拿走石子..就相当于几个奇数堆的石子在做Nim..( 如所给样例..2^3^4=5 不为零所以先手必败)为什么可以这样来转化?
     假设我们是先手...所给的阶梯石子状态的奇数堆做Nim先手能必胜...我就按照能赢的步骤将奇数堆的石子移动到偶数堆...如果对手也是移动奇数堆..我们继续移动奇数堆..如果对手将偶数堆的石子移动到了奇数堆..那么我们紧接着将对手所移动的这么多石子从那个偶数堆移动到下面的奇数堆...两次操作后...相当于偶数堆的石子向下移动了几个..而奇数堆依然是原来的样子...即为必胜的状态...就算后手一直在移动偶数堆的石子到奇数堆..我们就一直跟着他将石子继续往下移..保持奇数堆不变...如此做下去..我可以跟着后手把偶数堆的石子移动到0..然后你就不能移动这些石子了...所以整个过程..将偶数堆移动到奇数堆不会影响奇数堆做Nim博弈的过程..整个过程可以抽象为奇数堆的Nim博弈...
     其他的情况...先手必输的...类似推理...只要判断奇数堆做Nim博弈的情况即可...
     为什么是只对奇数堆做Nim就可以...而不是偶数堆 呢?...因为如果是对偶数堆做Nim...对手移动奇数堆的石子到偶数堆..我们跟着移动这些石子到下一个奇数堆...那么最后是对手把这些石子移动到了0..我们不能继续跟着移动...就只能去破坏原有的Nim而导致胜负关系的不确定 ...所以只要对奇数堆做Nim 判断即可知道胜负情况...

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#define maxn 100005
#define INF 2e15
typedef long long ll;
using namespace std;

vector<int> v[maxn];
int num[maxn], ans = 0;
void dfs(int j, int h){
	for(int i = 0; i < v[j].size(); i++){
		int k = v[j][i];
		if((h+1)&1)
		 ans ^= num[k];
		dfs(k, h+1);
	}
}
int main(){
//	freopen("in.txt", "r", stdin);
	int t;
	scanf("%d", &t);
	while(t--){
		ans = 0;
		int n, a;
		scanf("%d", &n);
		for(int i = 1; i < n; i++){
			scanf("%d", &a);
			v[a].push_back(i);
		}
		for(int i = 0; i < n; i++)
		  scanf("%d", num+i);
		dfs(0, 0);
		if(ans)
		 puts("win");
		else
		 puts("lose");
		for(int i = 0; i < n; i++)
		 v[i].clear();
	}
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值