2017 ICPC Shenyang H - Legends of the Three Kingdoms

挂着概率DP名字的模拟(
很容易想到dp[i][j][k][l][t][0,1,2]表示主公忠臣反贼内奸的血量,轮到t行动,三方势力分别的胜率
转移过程比较繁琐,看到网上基本上是DFS写的。这里提供一个循环的写法。
特别注意:这道题目一定要输出6位。
代码如下:

#include<iostream>
#include<stdio.h>
using namespace std;
double dp[40][40][40][40][4][3],maxx;
int i,j,k,l,cnt,h1,h2,h3,h4,tt,t;
int main()
{
	//主公忠臣胜利
	for (i=1;i<40;i++)
	{
		for (j=0;j<40;j++)
		{
			for (t=0;t<4;t++)
			{
				dp[i][j][0][0][t][0]=1;
				dp[i][j][0][0][t][1]=0;
				dp[i][j][0][0][t][2]=0;
			}
		}
	}
	//反贼胜利
	for (j=0;j<40;j++)
	for (k=0;k<40;k++)
	for (l=0;l<40;l++)
	for (t=0;t<4;t++)
	{
		dp[0][j][k][l][t][0]=0;
		dp[0][j][k][l][t][1]=1;
		dp[0][j][k][l][t][2]=0;
	}
	//内奸胜利 
	for (l=1;l<40;l++)
	{
		for (t=0;t<4;t++)
		{
			dp[0][0][0][l][t][0]=0;
			dp[0][0][0][l][t][1]=0;
			dp[0][0][0][l][t][2]=1;
		}
	}
	for (i=0;i<40;i++)
	for (j=0;j<40;j++)
	for (k=0;k<40;k++)
	for (l=0;l<40;l++)
	{
		if (((i==0)+(j==0)+(k==0)+(l==0))>=3) continue;
		if (i==0) continue;
		if (k+l==0) continue;
		//t=0;
		if (k>0) 	
		{
			dp[i][j][k][l][0][0]=dp[i][j][k-1][l][1][0];				
			dp[i][j][k][l][0][1]=dp[i][j][k-1][l][1][1];
			dp[i][j][k][l][0][2]=dp[i][j][k-1][l][1][2];
		}
		if (l>0)
		{
			if (k<=0||dp[i][j][k][l-1][1][0]>dp[i][j][k][l][0][0])
			{
				dp[i][j][k][l][0][0]=dp[i][j][k][l-1][1][0];
				dp[i][j][k][l][0][1]=dp[i][j][k][l-1][1][1];
				dp[i][j][k][l][0][2]=dp[i][j][k][l-1][1][2];
			}
			else if (k>0&&dp[i][j][k][l-1][1][0]==dp[i][j][k][l][0][0])
			{
				dp[i][j][k][l][0][0]=(dp[i][j][k][l-1][1][0]+dp[i][j][k][l][0][0])/2;
				dp[i][j][k][l][0][1]=(dp[i][j][k][l-1][1][1]+dp[i][j][k][l][0][1])/2;
				dp[i][j][k][l][0][2]=(dp[i][j][k][l-1][1][2]+dp[i][j][k][l][0][2])/2;
			}
		}
		//t=3;
		if (l==0)
		{
			dp[i][j][k][l][3][0]=dp[i][j][k][l][0][0];
			dp[i][j][k][l][3][1]=dp[i][j][k][l][0][1];
			dp[i][j][k][l][3][2]=dp[i][j][k][l][0][2];
		}
		else
		{
			maxx=0;
			cnt=0;
			if (i>0) if (dp[i-1][j][k][l][0][2]>maxx) maxx=dp[i-1][j][k][l][0][2];
			if (j>0) if (dp[i][j-1][k][l][0][2]>maxx) maxx=dp[i][j-1][k][l][0][2];
			if (k>0) if (dp[i][j][k-1][l][0][2]>maxx) maxx=dp[i][j][k-1][l][0][2];
			if (i>0) if (dp[i-1][j][k][l][0][2]==maxx) 
			{
				cnt++;
				dp[i][j][k][l][3][0]+=dp[i-1][j][k][l][0][0];
				dp[i][j][k][l][3][1]+=dp[i-1][j][k][l][0][1];
				dp[i][j][k][l][3][2]+=dp[i-1][j][k][l][0][2];
			}
			if (j>0) if (dp[i][j-1][k][l][0][2]==maxx) 
			{
				cnt++;
				dp[i][j][k][l][3][0]+=dp[i][j-1][k][l][0][0];
				dp[i][j][k][l][3][1]+=dp[i][j-1][k][l][0][1];
				dp[i][j][k][l][3][2]+=dp[i][j-1][k][l][0][2];
			}
			if (k>0) if (dp[i][j][k-1][l][0][2]==maxx) 
			{
				cnt++;
				dp[i][j][k][l][3][0]+=dp[i][j][k-1][l][0][0];
				dp[i][j][k][l][3][1]+=dp[i][j][k-1][l][0][1];
				dp[i][j][k][l][3][2]+=dp[i][j][k-1][l][0][2];
			}
			dp[i][j][k][l][3][0]=dp[i][j][k][l][3][0]/cnt;
			dp[i][j][k][l][3][1]=dp[i][j][k][l][3][1]/cnt;
			dp[i][j][k][l][3][2]=dp[i][j][k][l][3][2]/cnt;
		}
		//t=2;
		if (j==0)
		{
			dp[i][j][k][l][2][0]=dp[i][j][k][l][3][0];
			dp[i][j][k][l][2][1]=dp[i][j][k][l][3][1];
			dp[i][j][k][l][2][2]=dp[i][j][k][l][3][2];
		}
		else
		{
			if (k>0) 	
			{
				dp[i][j][k][l][2][0]=dp[i][j][k-1][l][3][0];				
				dp[i][j][k][l][2][1]=dp[i][j][k-1][l][3][1];
				dp[i][j][k][l][2][2]=dp[i][j][k-1][l][3][2];
			}
			if (l>0)
			{
				if (k<=0||dp[i][j][k][l-1][3][0]>dp[i][j][k][l][2][0])
				{
					dp[i][j][k][l][2][0]=dp[i][j][k][l-1][3][0];
					dp[i][j][k][l][2][1]=dp[i][j][k][l-1][3][1];
					dp[i][j][k][l][2][2]=dp[i][j][k][l-1][3][2];
				}
				else if (k>0&&dp[i][j][k][l-1][3][0]==dp[i][j][k][l][2][0])
				{
					dp[i][j][k][l][2][0]=(dp[i][j][k][l-1][3][0]+dp[i][j][k][l][2][0])/2;
					dp[i][j][k][l][2][1]=(dp[i][j][k][l-1][3][1]+dp[i][j][k][l][2][1])/2;
					dp[i][j][k][l][2][2]=(dp[i][j][k][l-1][3][2]+dp[i][j][k][l][2][2])/2;
				}
			}
		}
		//t=1;
		if (k==0)
		{
			dp[i][j][k][l][1][0]=dp[i][j][k][l][2][0];
			dp[i][j][k][l][1][1]=dp[i][j][k][l][2][1];
			dp[i][j][k][l][1][2]=dp[i][j][k][l][2][2];
		}
		else
		{
			maxx=0;
			cnt=0;
			if (i>0) if (dp[i-1][j][k][l][2][1]>maxx) maxx=dp[i-1][j][k][l][2][1];
			if (j>0) if (dp[i][j-1][k][l][2][1]>maxx) maxx=dp[i][j-1][k][l][2][1];
			if (l>0) if (dp[i][j][k][l-1][2][1]>maxx) maxx=dp[i][j][k][l-1][2][1];
			if (i>0) if (dp[i-1][j][k][l][2][1]==maxx)
			{
				cnt++;
				dp[i][j][k][l][1][0]+=dp[i-1][j][k][l][2][0];
				dp[i][j][k][l][1][1]+=dp[i-1][j][k][l][2][1];
				dp[i][j][k][l][1][2]+=dp[i-1][j][k][l][2][2];
			}
			if (j>0) if (dp[i][j-1][k][l][2][1]==maxx)
			{
				cnt++;
				dp[i][j][k][l][1][0]+=dp[i][j-1][k][l][2][0];
				dp[i][j][k][l][1][1]+=dp[i][j-1][k][l][2][1];
				dp[i][j][k][l][1][2]+=dp[i][j-1][k][l][2][2];
			}
			if (l>0) if (dp[i][j][k][l-1][2][1]==maxx)
			{
				cnt++;
				dp[i][j][k][l][1][0]+=dp[i][j][k][l-1][2][0];
				dp[i][j][k][l][1][1]+=dp[i][j][k][l-1][2][1];
				dp[i][j][k][l][1][2]+=dp[i][j][k][l-1][2][2];
			}
			dp[i][j][k][l][1][0]=dp[i][j][k][l][1][0]/cnt;
			dp[i][j][k][l][1][1]=dp[i][j][k][l][1][1]/cnt;
			dp[i][j][k][l][1][2]=dp[i][j][k][l][1][2]/cnt;
		}
	}
	scanf("%d",&tt);
	while (tt--)
	{
		scanf("%d%d%d%d",&h1,&h2,&h3,&h4);
		printf("%.6lf %.6lf %.6lf\n",dp[h1][h2][h3][h4][0][0],dp[h1][h2][h3][h4][0][1],dp[h1][h2][h3][h4][0][2]);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值