题目大意:一个跳棋游戏,每置一次骰子前进相应的步数。但是有的点可以不用置骰子直接前进,求置骰子次数的平均值。
题目分析:状态很容易定义:dp(i)表示在第 i 个点出发需要置骰子的次数平均值。则状态转移方程为:
dp(i)=singma(pk*dp(i+k))+1 (如果在 i 处必须置骰子才能前进)
dp(i)=dp(s) (如果在 i 处能直接到达s处)
代码如下:
# include<iostream> # include<cstdio> # include<vector> # include<cstring> # include<algorithm> using namespace std; int n,m; bool flag[100010]; double dp[100010]; vector<int>g[100010]; void init() { memset(dp,0,sizeof(dp)); memset(flag,false,sizeof(flag)); for(int i=0;i<=n;++i) g[i].clear(); int x,y; while(m--) { scanf("%d%d",&x,&y); g[y].push_back(x); } } double solve() { for(int i=0;i<g[n].size();++i){ int v=g[n][i]; flag[v]=true; } for(int i=n-1;i>=0;--i){ if(!flag[i]){ dp[i]=1.0; for(int j=1;j<=6;++j) dp[i]+=dp[i+j]/6.0; flag[i]=true; } for(int j=0;j<g[i].size();++j){ int v=g[i][j]; dp[v]=dp[i]; flag[v]=true; } } return dp[0]; } int main() { while(scanf("%d%d",&n,&m)&&(n+m)) { init(); printf("%.4lf ",solve()); } return 0; }