lightoj1030Discovering Gold
题意&思路:
有
n
n
n个格子,每个格子上有
a
i
a_i
ai个黄金。一个人的起始格子为1,每次投一个六面骰子,得到数字
x
x
x,如果当前位置为
i
i
i,且
x
+
i
<
=
n
x+i<=n
x+i<=n,就前进x格并捡起黄金,否则再投一次。问到n的格子上时,得到的黄金期望为多少。
因为每个走过的格子一定能拿到黄金,所以
d
p
[
i
]
=
a
[
i
]
dp[i]=a[i]
dp[i]=a[i]。
由于最后跳到
n
n
n点是确定的,所以我们可以得到
d
p
[
n
]
=
a
[
n
]
dp[n]=a[n]
dp[n]=a[n]。
所以我么可以得到:
d
p
[
n
−
1
]
=
a
[
n
−
1
]
+
d
p
[
n
]
\begin{aligned}dp[n-1]=a[n-1]+dp[n]\end{aligned}
dp[n−1]=a[n−1]+dp[n]
d
p
[
n
−
2
]
=
a
[
n
−
2
]
+
d
p
[
n
]
2
+
d
p
[
n
−
1
]
2
\begin{aligned}dp[n-2]=a[n-2]+\frac{dp[n]}{2}+\frac{dp[n-1]}{2}\end{aligned}
dp[n−2]=a[n−2]+2dp[n]+2dp[n−1]
d
p
[
n
−
3
]
=
a
[
n
−
3
]
+
d
p
[
n
]
3
+
d
p
[
n
−
1
]
3
+
d
p
[
n
−
2
]
3
\begin{aligned}dp[n-3]=a[n-3]+\frac{dp[n]}{3}+\frac{dp[n-1]}{3}+\frac{dp[n-2]}{3}\end{aligned}
dp[n−3]=a[n−3]+3dp[n]+3dp[n−1]+3dp[n−2]
……
d
p
[
i
]
=
a
[
i
]
+
d
p
[
i
+
6
]
6
+
d
p
[
i
+
5
]
6
+
d
p
[
i
+
4
]
6
+
d
p
[
i
+
3
]
6
+
d
p
[
i
+
2
]
6
+
d
p
[
i
+
1
]
6
\begin{aligned}dp[i]=a[i]+\frac{dp[i+6]}{6}+\frac{dp[i+5]}{6}+\frac{dp[i+4]}{6}+\frac{dp[i+3]}{6}+\frac{dp[i+2]}{6}+\frac{dp[i+1]}{6}\end{aligned}
dp[i]=a[i]+6dp[i+6]+6dp[i+5]+6dp[i+4]+6dp[i+3]+6dp[i+2]+6dp[i+1]
……
d
p
[
1
]
=
a
[
1
]
+
d
p
[
7
]
6
+
d
p
[
6
]
6
+
d
p
[
5
]
6
+
d
p
[
4
]
6
+
d
p
[
3
]
6
+
d
p
[
2
]
6
\begin{aligned}dp[1]=a[1]+\frac{dp[7]}{6}+\frac{dp[6]}{6}+\frac{dp[5]}{6}+\frac{dp[4]}{6}+\frac{dp[3]}{6}+\frac{dp[2]}{6}\end{aligned}
dp[1]=a[1]+6dp[7]+6dp[6]+6dp[5]+6dp[4]+6dp[3]+6dp[2]
所以倒着推一遍就行了。
代码:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<ctype.h>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
const int N=1e6+10;
const int mod=1e7+9;
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
int a[110];
double dp[110];
int main()
{
int t,l;
scanf("%d",&t);
for(l=1;l<=t;l++)
{
memset(dp,0,sizeof(dp));
int n,i,j;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
dp[i]=a[i];
}
for(i=n-1;i>=1;i--)
{
for(j=1;j<=6;j++)
{
int k=min(6,n-i);
dp[i]+=dp[i+j]/k;
}
}
printf("Case %d: %.7lf\n",l,dp[1]);
}
return 0;
}