Aeroplane chessTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6278 Accepted Submission(s): 3901 Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six faces with equal probability to face up and the numbers on the faces are 1,2,3,4,5,6). When Hzz is at grid i and the dice number is x, he will moves to grid i+x. Hzz finishes the game when i+x is equal to or greater than N.
Input There are multiple test cases.
Output For each test case in the input, you should output a line indicating the expected dice throwing times. Output should be rounded to 4 digits after decimal point.
Sample Input 2 0 8 3 2 4 4 5 7 8 0 0
Sample Output 1.1667 2.3441 |
【题意】
在编号为0-n的格子中下飞行棋?!起点为0终点为n,买掷一次骰子可以前进相应步数,有的位置可以直接飞到另一个位置,计算走到n点的掷骰子的期望次数。
【解题思路】
期望....给跪qaq感觉是世界上最恶心的东西之一,但是再恶心还是得做不是吗。
设dp[i]为到i点的期望次数,首先要清楚在n这个点因为已经到达终点,所以不用再掷骰子了,期望是0,那么dp[n]=0,既然已经知道最后一个点的期望,那么就可以从前往后推,问题就转换成了求dp[0]的期望。
因为i这个状态要转换成下一个状态可以掷骰子1-6,每掷一次筛子有1/6的可能,所以最终期望就是每次的步数*概率之和。别忘了最后得加1,因为从当前状态转换成下一个状态需要掷一次筛子。
【代码】
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int to[maxn];
double dp[maxn];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m) && n || m)
{
memset(dp,0,sizeof(dp));
memset(to,0,sizeof(to));
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
to[x]=y;
}
for(int i=n-1;i>=0;i--)
{
if(to[i])
{
dp[i]=dp[to[i]];
continue;
}
for(int j=i+1;j<=i+6;j++)
dp[i]+=dp[j]/6;
dp[i]+=1;
}
printf("%.4f\n",dp[0]);
}
return 0;
}