2014 Winter Programming School, Kharkiv, day 1 (E. Kapun) K.A game (High)(概率dp模拟/消元)

题目

Alex和Bob玩博弈游戏,Alex开始有m1张牌,Bob有m2张牌,(1<=m<=50)

Alex赢得概率是P%,赢的话就从Bob那里拿n1张牌,输的话给Bob n2张牌(0<=P<=100,1<=n<=50)

0张牌时仍能打,但0张牌且不能给牌的时候,游戏结束

问Alex的胜率

题解

模拟1W轮,答案就很接近真实答案了…

dp[i][j]代表第i轮时Alex有j张牌的胜率,考虑其后继

考虑总牌数不变,故

如果+n1直接>=m1+m2,就必胜,概率为1

如果-n2直接<0,就必败,概率为0

否则,乘上对应转移的概率

代码

#include<bits/stdc++.h>
using namespace std; 
typedef long long ll;
const int N=105;
int n,n1,n2,m1,m2,P,f;
double dp[2][N],p;
int main()
{
	scanf("%d%d%d%d%d",&n1,&n2,&m1,&m2,&P);
	p=P/100.0;
	n=m1+m2;
	//由于card=0&&p=100可以玩 故有概率 
	for(int i=1;i<=10000;++i,f^=1)
	{
		for(int j=0;j<=n;++j)
		{
			dp[f][j]=0;
			if(j+n1<=n)dp[f][j]+=p*dp[f^1][j+n1];//赢的后继 
			else dp[f][j]+=p;//直接游戏结束必胜的后继 
			if(j-n2>=0)dp[f][j]+=(1.0-p)*dp[f^1][j-n2];//输但是游戏没结束的后继 
		} 
	}
	printf("%.8lf\n",dp[0][m1]);//初始情况有m1 
	return 0;
} 
发布了467 篇原创文章 · 获赞 53 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/Code92007/article/details/101356425
今日推荐