buptoj:Study sister's dragon

时间限制 1000 ms  内存限制 65536 KB

题目描述

Study sister plays the game coc everyday. One day, she asked Study brother to donate a dragon into her castle, but Study brother refused because the dragon cost too much.
At last, they decide to play a rock game, and if Study brother lose the game, he would donate a dragon.
There are several piles of rocks, and they pick some rocks from one pile alternatively. According to game theory, it is easy to tell who would win the game. So Study brother made a new rule. Before the game starting, Study brother will pick a random number of rocks(might be zero) but not all of them from each pile, and then they start play the game.
Now Study brother wants to know his chance to win.
As a gentleman, Study brother alway let Study sister to pick first when they play the game.

输入格式

There are several test case. The first line of each test case contains an integer n, means the number of piles. Then a line with n numbers shows the number of rocks of each pile. n <= 1000. The number of rocks in each pile is smaller than 128.

输出格式

For each test case, print on line, Study brother's probability of winning.

输入样例

2
2 2

输出样例


0.500000

hint
They may get 1,1 or 1,2 or 2,1 or 2,2,so the the probability is 0.5

概率dp,nim模型。

代码:

#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;

#define INF 0x333f3f3f

const ll mod = 1000000007;
const int maxn = 1e5 + 5;
const double PI = acos(-1.0);

int n;
int val[maxn];
double dp[2][1025];

void solve()
{
	int i, j, k;

	for (i = 1; i <= n; i++)
	{
		scanf("%d", &val[i]);
	}
	memset(dp, 0, sizeof(dp));
	int now = 1, pre = 0;
	dp[pre][0] = 1;

	for (i = 1; i <= n; i++)
	{
		memset(dp[now], 0, sizeof(dp[now]));
		for (j = 0; j <= 128; j++)
		{
			for (k = 1; k <= val[i]; k++)
			{
				dp[now][j^k] += (dp[pre][j] / (double)val[i]);
			}
		}
		swap(now, pre);
	}

	printf("%.6lf\n", dp[pre][0]);
}

int main()
{
/*
#ifndef ONLINE_JUDGE  
	freopen("i.txt", "r", stdin);
	freopen("o.txt", "w", stdout);
#endif
*/
	while (scanf("%d", &n) != EOF)
	{
		solve();
	}
	//system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值