lightoj 1030 - Discovering Gold(概率DP)
You are in a cave, a long cave! The cave can be represented by a 1 x N grid. Each cell of the cave can contain any amount of gold.
Initially you are in position 1. Now each turn you throw a perfect 6 sided dice. If you get X in the dice after throwing, you add X
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case contains a blank line and an integer N (1 ≤ N ≤ 100) denoting the dimension of the cave. The next line contains N space separated integers. The ith
Output
For each case, print the case number and the expected number of gold you will collect. Errors less than 10-6 will be ignored.
Sample Input
3
1
101
2
10 3
3
3 6 9
Sample Output
Case 1: 101.0000000000
Case 2: 13.000
Case 3: 15
PS:題意:現在有n個山洞,編號為1-n,每個洞裡都有一定數量的黃金,現在有一枚骰子,上面有1-6的數字,比如現在位置是i,擲骰子的數目為x,則可以到達洞穴i+x,如果i+x超過了n,則重新擲。現在問在洞穴n拿到黃金的期望。
我們現在的位置在1號位,設期望為E(1)。因為我們要求從1到n的期望,所以我們遍歷的時候應該從後往前遍歷,這樣才能保證我們的起始位置是1。因為骰子有六面,所以我們可以得到公式,E(i)=(E(i+1)+E(i+2)+E(i+3)+E(i+4)+E(i+5)+E(i+6))/6+gold[i]。因為我們要保證起點是從1開始所以我們要從後往前遍歷。
我們已樣例三為例,3,6,9.
E(3)=9。因為在三號位不可能擲骰子擲出負數到2號位或1號位。
E(2)=6+E(3)/1=15。因為現在在2號位只能擲到三號位。
E(1)=(E(2)+E(3))/2+gold[1]=15。其實也可以解釋,現在在一號位,剩下2號位和3號位的概率各佔一半。
#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=1e3+10;
const int mod=10007;
const int inf=1e8;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
typedef long long ll;
using namespace std;
double dp[maxn];
int main()
{
int t,Case=1;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf",&dp[i]);
for(int i=n-1;i>=1;i--)
{
int temp=min(6,n-i);//骰子最大數為6
for(int j=1;j<=temp;j++)//從後往前遍歷
dp[i]+=(double)dp[i+j]/temp;
}
printf("Case %d: %.7f\n",Case++,dp[1]);
}
return 0;
}