ZOJ 3329 One Person Game (概率dp 难)

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 dice are fair dice, so the probability of rolling each value, 1 to
K1, K2, K3 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
n, K1, K2, K3,
a, b, c (0 <= n <= 500, 1 < K1,
K2, K3 <= 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

参考  bin神 的博客,如果自己做绝对做不出,数学不好真是硬伤

http://www.cnblogs.com/kuangbin/archive/2012/10/03/2710648.html

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>

#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define eps 1e-8
//typedef __int64 ll;

#define fre(i,a,b)  for(i = a; i <b; i++)
#define free(i,b,a) for(i = b; i >= a;i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define ssf(n)      scanf("%s", n)
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define bug         pf("Hi\n")

using namespace std;

#define INF 0x3f3f3f3f
#define N 1005

double p[N],dp[N];
double A[N],B[N];
int a,b,c,n,k1,k2,k3;
double pp;

int main()
{
	int i,j,s;
	int t;
	sf(t);
	while(t--)
	{
        sf(n);
		sfff(k1,k2,k3);
		sfff(a,b,c);
		mem(p,0);
		pp=1.0/k1/k2/k3;

		fre(i,1,k1+1)
		 fre(j,1,k2+1)
		  fre(s,1,k3+1)
		    if(i!=a||j!=b||s!=c)
			  p[i+j+s]+=pp;

	   mem(A,0);
	   mem(B,0);

	   free(i,n,0)
	    {
             A[i]=pp;
             B[i]=1;

	    	fre(j,3,k1+k2+k3+1)
	    	  {
	    	  	 A[i]+=p[j]*A[i+j];
	    	  	 B[i]+=p[j]*B[i+j];
	    	  }
	    }

		double ans=B[0]/(1-A[0]);

		pf("%.15f\n",ans);

	}
    return 0;
}
时间: 2024-11-01 11:40:39

ZOJ 3329 One Person Game (概率dp 难)的相关文章

[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

先吐槽几句真心给数学跪了 题意: 有三个均匀的骰子,分别有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 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 K3faces. All the d

ZOJ 3329 One Person Game 概率DP 期望 难度:2

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3754 本题分数为0的概率不确定,所以不能从0这端出发. 设E[i]为到达成功所需的步数,明显i>n时E[i]=0,当0<i<=n时E[i]=sigma(E[i+k]*pk)+E[0]*p0,(k是可以投出的除了恰为a,b,c以外的骰子之和), 在这个公式里,E[i]和E[0]都是未知的,设E[0]=x,则 E[i]=sigma(E[i+k]*pk)+x*p0+1, 因

ZOJ 3640 Help Me Escape 概率dp

有一个吸血鬼被困了,有n条路可以逃出去,每条路有一个难度c[],他初始的战斗力是f,对于第i条路,若f > c[i]他花t[i]天就能出去,否则,他就停留一天,同时战斗力增加c[i]然后再选一条路走出去,他走每条路的概率是相同的.问他逃出去的天数的期望. 设dp[i]表示在战斗力为i时逃出去的期望值,那么可推出状态方程 dp[i] = 1/n * t[j](c[j] > i),dp[i] = 1/n * (1+dp[ i+c[j] ] )( c[j] <= i). 需要注意的是终态的确定

zoj 3640 Help Me Escape (概率dp 递归求期望)

题目链接 Help Me Escape Time Limit: 2 Seconds      Memory Limit: 32768 KB Background     If thou doest well, shalt thou not be accepted? and if thou doest not well, sin lieth at the door. And unto thee shall be his desire, and thou shalt rule over him.  

ZOJ 3329-One Person Game(概率dp,迭代处理环)

题意: 三个色子有k1,2,k3个面每面标号(1-k1,1-k2,1-k3),一次抛三个色子,得正面向上的三个编号,若这三个标号和给定的三个编号a1,b1,c1对应则总和置零,否则总和加上三个色子标号和,直到总和不小于n时结束,求抛色子的期望次数. 分析: 该题状态好分析 dp[i]表示和为i时的期望次数,dp[0]是答案 dp[i]=sum(dp[i+tmp]*p[tmp])+dp[0]*p0+1(tmp是三个色子可得到的标号和); 第一次看到这样的方程不怎么解,看了题解才知道用迭代法,每个d

zoj--3822--第二题概率dp

这题 比上次那个概率dp难多了 自己感觉... 而且 这题的来源是 我上次去的 牡丹江区域赛.. FML------不想多说了 dp[ i ][ j ][ k ]表示用 k 个棋子占领了 I 行 J 列 < 每一个坐标为(x,y)的棋子都可以占领它所在的第 X 行 第 Y 列 > 那么假如现在已经放了K个棋子 并且占领了 I 行 J列 那么对于将要放下去的第(k+1)个棋子 将会有4种不同情况的发生<保证棋盘还有空格在还可以继续放的情况下> 这里的 n * m - k 就是指一共有

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