题意:
n+1格飞行棋,编号0-n,从0格开始,每次扔一个色子,得到的点数就向前走几步,但有有些格子到达后可以直接飞到后面的格子,
当到达>=n的地方结束,求结束扔色子的期望次数。
分析:
dp[i]表示i格到结束需要的期望次数,dp[n]-dp[n+5]是0,dp[0]即为所求,先处理直接飞的情况
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<11 #define All 1,N,1 #define N 100010 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; double dp[N]; //fly[i]i格可以最终飞到的格子 int fly[N],n,m; void solve(){ memset(dp,0,sizeof(dp)); for(int i=n-1;i>=0;--i){ if(fly[i]!=-1){ dp[i]=dp[fly[i]];//可由前面的格子飞过来 } else{ //6种情况 for(int j=1;j<=6;++j) dp[i]+=dp[i+j]/6.0; dp[i]+=1.0; } } printf("%.4lf\n",dp[0]); } int main() { while(~scanf("%d%d",&n,&m)){ if(n==0&&m==0)break; memset(fly,-1,sizeof(fly)); int u,v; while(m--){ scanf("%d%d",&u,&v); fly[u]=v; } for(int i=0;i<=n;++i){ int j=fly[i]; if(j==-1)continue; while(fly[j]!=-1){ j=fly[j]; } fly[i]=j; } solve(); } return 0; }
时间: 2024-10-10 15:19:18