有一个 1 * n 的表格,每个格子上有一些金币,刚开始在第一个格子上,在当前位置,每次我们可以摇一个 6 面筛子,摇到几向前走几步,当摇的点数太大,使人走出表格的时候,要重新摇筛子直到能不走出表格位置,走到第 n 个格子位置,求走到 n 的期望得到的金币数量.
思路
期望 dp,从后往前递推,dp [i] 表示从 i 位置到 n 位置的期望得到的金币数,
dp [i] 可以从 i 后面的 min (6, n - i) 个位置转移过来,假设这个转移过来的位置为 x,
那么状态转移方程为 dp [i] += dp [x] /min (6, n - i),
注意初始化 i 位置的 dp [i] 值为,那个格子中的金币的数量
链接
#include<bits/stdc++.h>
using namespace std;#definedbdouble#definelllonglong#definescscanf#defineprprintf#definefifirst#definesesecond#definepbpush_back#definem_pmake_pair#definePirpair<int,int>#defineinf0x3f3f3f3f#defineINF0x3f3f3f3f3f3f3f3f/*==========ACMer===========*/constint N =1005;int a[N];
db dp[N];intmain(){int T, cas =1;sc("%d",&T);while(T --){int n;sc("%d",&n);for(int i =1; i <= n; i ++)sc("%d",&a[i]);memset(dp,0,sizeof dp);
dp[n]= a[n];for(int i = n -1; i >=1; i --){int cnt =min(6, n - i);
dp[i]= a[i];for(int j = i +1; j <= i + cnt; j ++)//注意这里的 j <= i + cnt{
dp[i]+= dp[j]/ cnt;}}pr("Case %d: %f\n", cas ++, dp[1]);}return0;}