ZOJ 3329 One Person Game

题意:有三个骰子,分别有k1,k2,k3个面。

每次连续掷三个骰子,每个骰子的每个面出现的概率相等,如果三个面分别为a,b,c则分数置0,否则加上三个骰子的分数之和。

当分数大于n时结束。求游戏的期望步数。初始分数为0。

做法:

设dp[i]表示达到i分时到达目标状态的期望,pk为投掷k分的概率,p0为回到0的概率

则dp[i]=∑(pk*dp[i+k])+dp[0]*p0+1;

都和dp[0]有关系,而且dp[0]就是我们所求,为常数

设dp[i]=A[i]*dp[0]+B[i];

代入上述方程右边得到:

dp[i]=∑(pk*A[i+k]*dp[0]+pk*B[i+k])+dp[0]*p0+1

=(∑(pk*A[i+k])+p0)dp[0]+∑(pk*B[i+k])+1;

明显A[i]=(∑(pk*A[i+k])+p0)

B[i]=∑(pk*B[i+k])+1

先递推求得A[0]和B[0].

那么  dp[0]=B[0]/(1-A[0]);

另外,关于边界问题,若i>n,因为dp[i]=A[i]*dp[0]+B[i]=0,A[i]>=0,B[i]>=0,dp[0]>0,所以A[i]=0,B[i]=0。

于是就可以递推了。

#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<climits>
#include<list>
#include<iomanip>
#include<stack>
#include<set>
using namespace std;
double x[510],y[510];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,k1,k2,k3,a,b,c;
		cin>>n>>k1>>k2>>k3>>a>>b>>c;
		double p=1.0/(k1*k2*k3);
		for(int i=n;i>-1;i--)
		{
			x[i]=p;
			y[i]=1;
			for(int j=1;j<=k1;j++)
				for(int k=1;k<=k2;k++)
					for(int ii=1;ii<=k3;ii++)
						if((j!=a||k!=b||ii!=c)&&i+j+k+ii<=n)
						{
							x[i]+=x[i+j+k+ii]*p;
							y[i]+=y[i+j+k+ii]*p;
						}
		}
		printf("%.9f\n",y[0]/(1-x[0]));
	}
}

Time Limit: 1 Second      Memory Limit: 32768 KB      Special Judge



There is a very simple and interesting one-person game. You have 3 dice, namely Die1Die2 and Die3Die1 has K1 faces. Die2 has K2 faces. Die3 has K3 faces.
All the dice are fair dice, so the probability of rolling each value, 1 to K1K2K3 is exactly 1 / K1, 1 / K2 and 1 / K3. You have a counter,
and the game is played as follow:

  1. Set the counter to 0 at first.
  2. Roll the 3 dice simultaneously. If the up-facing number of Die1 is a, the up-facing number of Die2 is b and the up-facing number of Die3 is c, set the counter to 0. Otherwise,
    add the counter by the total value of the 3 up-facing numbers.
  3. If the counter‘s number is still not greater than n, go to step 2. Otherwise the game is ended.

Calculate the expectation of the number of times that you cast dice before the end of the game.

Input

There are multiple test cases. The first line of input is an integer T (0 < T <= 300) indicating the number of test cases. Then T test cases follow. Each test
case is a line contains 7 non-negative integers nK1K2K3abc (0 <= n <= 500, 1 < K1K2K3 <=
6, 1 <= a <= K1, 1 <= b <= K2, 1 <= c <= K3).

Output

For each test case, output the answer in a single line. A relative error of 1e-8 will be accepted.

Sample Input

2
0 2 2 2 1 1 1
0 6 6 6 1 1 1

Sample Output

1.142857142857143
1.004651162790698

Author: CAO, Peng

Source: The 7th Zhejiang Provincial Collegiate Programming Contest

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-01 19:43:16

ZOJ 3329 One Person Game的相关文章

zoj 3329 概率dp

看了这么多,也就是个递推 1 /* 2 ZOJ 3329 3 题意:有三个骰子,分别有k1,k2,k3个面. 4 每次掷骰子,如果三个面分别为a,b,c则分数置0,否则加上三个骰子的分数之和. 5 当分数大于n时结束.求游戏的期望步数.初始分数为0 6 7 设dp[i]表示达到i分时到达目标状态的期望,pk为投掷k分的概率,p0为回到0的概率 8 则dp[i]=∑(pk*dp[i+k])+dp[0]*p0+1; 9 都和dp[0]有关系,而且dp[0]就是我们所求,为常数 10 设dp[i]=A

[ACM] ZOJ 3329 One Person Game (概率DP,有环,巧妙转化)

One Person Game Time Limit: 1 Second      Memory Limit: 32768 KB      Special Judge There is a very simple and interesting one-person game. You have 3 dice, namely Die1, Die2 and Die3. Die1 has K1 faces. Die2 has K2 faces. Die3 has K3 faces. All the

ZOJ 3329 One Person Game:期望dp【关于一个点成环——分离系数】

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3329 题意: 给你面数分别为k1,k2,k3的三个骰子. 给定a,b,c三个整数. 三个骰子每扔一次,若骰子朝上的点数分别为a,b,c,则分数清零,否则当前分数+=骰子点数之和. 当分数 > n时游戏结束. 问你扔骰子次数的期望. 题意: 表示状态: dp[i] = rest steps (当前分数为i时,剩余步数的期望) 找出答案: ans = dp[0] 刚

ZOJ 3329 One Person Game 带环的概率DP

每次都和e[0]有关系 通过方程消去环 dp[i] = sigma(dp[i+k]*p)+dp[0]*p+1 dp[i] = a[i]*dp[0]+b[i] dp[i] = sigma(p*(a[i+k]*dp[0]+b[i+k]))+dp[0]*p+1 a[i] = sigma(a[i+k]*p)+p b[i] = sigma(b[i+k]*p)+1 #include <cstdio> #include <cstring> using namespace std; double

ZOJ 3329 期望DP

题目大意: 给定3个已经规定好k1,k2,k3面的3个色子,如果扔到a,b,c则重新开始从1 计数,否则不断叠加所有面的数字之和,直到超过n,输出丢的次数的数学期望 我们在此令dp[]数组记录从当前数值到结束的数学期望 假如有3个面数都为2的色子 那么dp[i] = 1.0 / 2/2/2 * dp[0] + 1.0/8*dp[i+3] +3.0/8*dp[i+4]+3.0/8*dp[i+5]+1.0/8*dp[i+6] + 1 当然那些下标大于i的dp值均为0 可是我们这样从后往前推会导致无法

ZOJ 3329 【概率DP】

题意: 给你三个均匀k面筛子. 分别有k1 k2 k3个面,每个面朝上的概率是相等的. 如果第一个筛子出现a第二个筛子出现b第三个筛子出现c那么置零. 否则在当前和加上三个点数之和. 求当前和大于n需要的步数的期望. 思路: 一开始状态转移搞错了,手推公式交了WA,后来想了想状态转移的过程发现每个状态都跟0状态有关系,但是dp[0]不确定,但是幸运的是这是一个线性变换,所以状态转移的时候记录一下dp[0]的系数,最后移项输出就好了. dp[i]=dp[i+x]*(k1*k2*k3);(x=i+j

zoj 3329 One Person Game 概率dp

先吐槽几句真心给数学跪了 题意: 有三个均匀的骰子,分别有k1,k2,k3个面,初始分数是0, 当掷三个骰子的点数分别为a,b,c的时候,分数清零,否则分数加上三个骰子的点数和, 当分数>n的时候结束.求需要掷骰子的次数的期望. 题解: 设 E[i]表示现在分数为i,到结束游戏所要掷骰子的次数的期望值. 显然 E[>n] = 0; E[0]即为所求答案; E[i] = ∑Pk*E[i+k] + P0*E[0] + 1; (Pk表示点数和为k的概率,P0表示分数清零的概率) 由上式发现每个 E[

ZOJ 3329:One Person Game 概率DP求期望(有环)

One Person Game 题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3754 题意: 玩一个掷骰子的游戏,同时掷三个筛子,每次掷筛子都会得到分数(三个筛子掷得的数的合),规则如下:   初始分数为0,如果一号骰子掷得a且二号骰子掷得b,同时三号筛子掷得c,则分数归零 当分数大于n时游戏结束 求直到游戏结束掷骰子的次数的期望 题解: 设E[i]为初始分数为0时所求的期望,则E[n+1]=0,E[0]即所求

zoj 3329 One Person Game(有环的概率dp)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3754 开始看错题意了,以为没翻到a,b,c时要在原来的基础上加a+b+c,按我的意思推出来一个公式,没想到样例还过了,简直无法debug. 公式很好推,设dp[i]表示当前为i分时到达目标状态需要投掷的期望,可转移到两个状态dp[0]和dp[i+k].设转移到dp[0] 的概率是p0,转移到dp[i+k]的概率是pk.那么可得dp[i] = p0*dp[0] + pk*dp[