列表

详情


NC214971. zzugzx(vs)Kurisu

描述

zzugzx和Kurisu做游戏,轮流扔n个回合骰子,骰子的m个面是[0,m-1],由zzugzx先手

每个人需要维护一个长n的m进制数,开始两个人的n个位置都是空的

每次会随机摇到一个数,然后可以选择填充到任意一个未被填充的位置

众所周知,zzugzx和Kurisu都足够聪明,问最后zzugzx胜利的概率.

(只有最后zzugzx的数字大于Kurisu才算赢,否则Kurisu赢)

输入描述

两个数n,m (m>1)

数据保证

输出描述

一行输出zzugzx获胜的概率. 你只需要保证误差在1e-6内即可

示例1

输入:

1 2

输出:

0.2500000

说明:

自己模拟...

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 1880ms, 内存消耗: 163856K, 提交时间: 2021-02-03 19:20:05

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int mod=998244353;
const int inf=0x3f3f3f3f;
const int maxn=1e5+5;
int n,m;
double f[5005][5005];
bool vis[5005][5005];
double dfs(int num,int x,int y)
{
	if(vis[x][y])return f[x][y];
	if(!num)return x>y;
	vis[x][y]=true;
	double res=0;
	for(int j=1;j<=m;j++){
		if(num%2==0)res=0;
		else res=1;
		for(int i=0,v=num&1?y:x,b=1;i<n;i++,v/=m+1,b*=m+1){
			if(v%(m+1))continue;
			if(num%2==0)res=max(res,dfs(num-1,x+j*b,y));
			else res=min(res,dfs(num-1,x,y+j*b));
		}
		f[x][y]+=res/m;
	}
	return f[x][y];
}
int main()
{
	scanf("%d%d",&n,&m);
	printf("%.7lf\n",dfs(n*2,0,0));
}

上一题