Acedream 1113 The Arrow(概率DP)

来源:互联网 发布:阿里云哪里的服务器好 编辑:程序博客网 时间:2024/06/05 09:44

传送门
The Arrow
Time Limit:1000MS Memory Limit:64000KB 64bit IO Format:%lld & %llu
Submit

Status
Description
The history shows that We need heroes in every dynasty. For example, Liangshan Heroes. People hope that these heroes can punish the bad guys and recover the justice. Nowadays, we also need heroes to provent us from being chopped, or being attacked by a bomb.

Kuangbin is a very very very very very…. (very * 1e9 ) good boy, after he knows The Arrow, he want to be The Arrow of China. But he is also a little afraid of being killed by the bad guys. So he decides to throw dices to make the decision.

The dice is a cube with 1 2 3 4 5 6 on it’s sides. When he throws a dice, every number is of the same probablity to appear. He will write down a number N in the paper at first, and then throw the dice. When the sum of the number he throwed is less than N, he will keep throwing. But if the sum exceeds N, this throwing does not count.

For example, If the sum is 5,and N is 6, if we throw 2, 5 + 2 > 6, then the sum keeps to be 5.

If he can end the throwing in a certain time, he will make the decision to become The Arrow.

Now , kuangbin wonders that what’s the expectation of the time of throwing dices.

Input
First line, The number of cases t <= 100

In the next t lines, there will be t numbers.

every number is not bigger than 100000

Output
Each test output a number rounded to the second digit.
Sample Input
1
1
Sample Output
6.00

题目大意:
一个人扔骰子,按照骰子的点数从当前位置加上骰子的点数到达(假设当前是x点) x+y点,如果 x+y>n点 那么还在x点不移动,求的是能够从 0 点走到 n 点的所扔的骰子的次数的概率期望

解题思路:
这个我们假设DP[i]表示的就是从 i 点到 n 点的期望,那么DP[i]等于什么呢,我们可以这么想,我们首先扔一个骰子,这是扔了1次了,这个骰子的点数可能是[1,6]区间的任意一个数,那么概率是1/6*DP[i+j] ( j表示的就是扔的点数 ),if(i+j>n) 应该是不动的所以 x/6*DP[i] ( x表示的是原地不动的次数 )
那么DP[i]的公式就有:

DP[i]=1+DP[i+1]6+DP[i+2]6+DP[i+3]6+...+DP[i+6]6+x6DP[i]

只要推出了这个公式然后就是编程了,还是比较好写的(注意的是 第一层循环是从 n-1 循环到 0):

My Code:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int MAXN = 1e5+5;double dp[MAXN];int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n;        scanf("%d",&n);        memset(dp, 0, sizeof(dp));        for(int i=n-1; i>=0; i--)        {            int cnt = 0;            double sum = 0;            for(int j=1; j<=6; j++)            {                if(i+j > n)                    cnt++;                else                    dp[i] += dp[i+j]/6;            }            dp[i] = (dp[i]+1)/(6-cnt)*6;        }        printf("%.2lf\n",dp[0]);    }    return 0;}
0 0
原创粉丝点击