hdu 4405 Aeroplane chess (概率dp)
/*
題目大意:
問從0到n所花費時間平均時間。每次有投骰子,投到幾就走幾步。當然了,還有近道。
題目分析:
假設現在在i,那麼接下來有六種可能的走法,分別是:
i到i+1,在由i+1到結束
i到i+2,在由i+2到結束
i到i+3,在由i+3到結束
i到i+4,在由i+4到結束
i到i+5,在由i+5到結束
i到i+6,在由i+6到結束
其中每一個可能的走法發生的概率為n為1/6。那麼不妨定義dp(i),表示從i走到結束的期望。
那麼有下面的等式:
dp(i-1) = sum((dp((i-1)+j)+1)*p) 其中j ∈[0,6]。
當(i-1)+j >= n時,只需要時間1就可以結束。
當有近道(i,j)時,可以直接跳過去。dp(i)=dp(j)。
*/
# include
# include
# include
# include
using namespace std;
int n;
double dp[100010];
int h[100010];
void slove()
{
memset(dp,0,sizeof(dp));
for(int i=n; i>=1; i--)
{
double p=1.0/6.0;//骰子概率
for(int j=1; j<=6; j++)
{
int id=h[i-1];
if(id!=-1)//直接過來,不用擲骰子
dp[i-1]=dp[id];
else
{
if((i-1)+j>=n)
dp[i-1]+=p;
else
dp[i-1]+=(dp[(i-1)+j]+1)*p;
}
}
}
}
int main()
{
int m,a,b;
while(~scanf("%d%d",&n,&m),n+m)
{
memset(h,-1,sizeof(h));
while(m--)
{
scanf("%d%d",&a,&b);
h[a]=b;
}
slove();
printf("%.4lf\n",dp[0]);
}
return 0;
}