[ZOJ3329] One Person Game 题解

One Person Game

题意

\(~~~~\) 有三个骰子,分别有 \(k_1,k_2,k_3\) 个面。 每次掷骰子,如果三个面分别为 \(a,b,c\) 则分数清零,否则加上三个骰子的点数之和。 当分数达到 \(n\) 及以上时结束。求游戏结束的期望步数。


题解

\(~~~~\) 期望 \(dp\) 好题。

\(~~~~\) 套路化地,我们设 \(dp_i\) 表示你有 \(i\) 分时结束的期望步数。则 \(dp_n=0\) ,答案为 \(dp_0\) 。进行倒推。

\(~~~~\) 设: \(p_i\) 表示丢骰子丢出的点数和为 \(i\) 且能加入分数的概率,特殊地,设 \(dp_0\) 表示丢出清零的概率。不难发现它等于 \(\dfrac{1}{k_1k_2k_3}\).

\(~~~~\) 考虑某个状态可以变为哪些状态,则有转移方程:

\[dp_i=1+dp_0\times p_0+\sum_{j=1}^{k1+k2+k3} dp_{i+j} \times p_j \]

\(~~~~\) 然后你就会发现转移方程里面有 \(dp_0\) 项,而倒推时 \(dp_0\) 恰恰是最后求出来的。

\(~~~~\) 那怎么办呢?这题不可做,换一道。

\(~~~~\) 观察式子,若设 \(dp_0\) 为未知数,发现它形似一次函数: \(dp_i=a\times dp_{0}+b\) .不妨设 \(a_i,b_i\) 为对应的满足条件的 \(a,b\).

\(~~~~\) 先从特殊情况考虑,当 \(i=n\) 时,\(dp_i=0\),因此 \(a_i=0,b_i=0\)

\(~~~~\) 然后我们把原来的转移方程中的 \(dp_{i+j}\) 也改写一下形式:

\[dp_i=1+dp_0\times p_0+\sum_{j=1}^{k1+k2+k3} (a_{i+j}\times dp_0+b_{i+j}) \times p_j \]

\(~~~~\) 再稍稍展开一下:

\[dp_i=dp_0\times (p_0+\sum_{j=1}^{k_1+k_2+k_3}a_{i+j}\times p_j) +1+\sum_{j=1}^{k_2+k_2+k_3} b_{i+j}\times p_j \]

\(~~~~\) 不难发现:

\[a_i=p_0+\sum_{j=1}^{k_1+k_2+k_3}a_{i+j}\times p_j \]

\[b_i=1+\sum_{j=1}^{k_2+k_2+k_3} b_{i+j}\times p_j \]

\(~~~~\) 因此这样转移 \(a,b\) 即可。

\(~~~~\) 再来考虑答案:\(dp_0=a_0 \times dp_0+b_0\) ,因此 \(dp_0=\dfrac{b_0}{1-a_0}\),即答案。


代码

查看代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
double p[20];
double A[505],B[505];
int main() {
	int T,n,k1,k2,k3,a,b,c;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d %d %d %d %d %d %d",&n,&k1,&k2,&k3,&a,&b,&c);
		p[0]=1.0/k1/k2/k3;
		for(int i=1;i<=k1;i++)
		{
			for(int j=1;j<=k2;j++)
			{
				for(int k=1;k<=k3;k++)
				{
					if(i==a&&j==b&&k==c) continue;
					p[i+j+k]+=1;
				}
			}
		}
		for(int i=3;i<=k1+k2+k3;i++) p[i]=p[i]/(double)(k1*k2*k3);
		for(int i=n;i>=0;i--)
		{
			A[i]=p[0];B[i]=1.0;
			for(int j=3;j<=k1+k2+k3;j++)
			{
				if(i+j>n) continue;
				A[i]+=A[i+j]*p[j];
				B[i]+=B[i+j]*p[j];
			}
		}
		printf("%.15f\n",(double)B[0]/(1.0-A[0]));
		memset(A,0,sizeof(A));
		memset(B,0,sizeof(B));
		memset(p,0,sizeof(p));
	}
	return 0;
}
posted @ 2020-08-25 12:57  Azazеl  阅读(130)  评论(0编辑  收藏  举报