HDU 4405 Aeroplane chess(概率dp)
http://acm.hdu.edu.cn/showproblem.php?pid=4405
题意:
有个屌丝喜欢玩飞行棋,现在棋盘就编号为0~n,起点为0,终点为n,只要最后大于等于n就可以,还存在一些跳跃的格子,即可以从u跳到v。问掷骰子的期望次数。
思路:
逆推计算期望即可。需要注意的就是跳跃的情况,也就是说如果u和v之间有边,那么d[u]=d[v]。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 #include<set> 11 using namespace std; 12 typedef long long ll; 13 const int INF = 0x3f3f3f3f; 14 const int maxn=100000+10; 15 16 int n, m; 17 double d[maxn]; 18 vector<int> G[maxn]; 19 20 int main() 21 { 22 //freopen("in.txt","r",stdin); 23 while(~scanf("%d%d",&n,&m)) 24 { 25 if(!n && !m) break; 26 for(int i=1;i<=n;i++) G[i].clear(); 27 for(int i=0;i<m;i++) 28 { 29 int u,v; 30 scanf("%d%d",&u,&v); 31 G[u].push_back(v); 32 } 33 memset(d,0,sizeof(d)); 34 for(int i=n-1;i>=0;i--) 35 { 36 if(G[i].size()) d[i]=d[G[i][0]]; 37 else 38 { 39 d[i]=1; 40 for(int j=1;j<=6;j++) 41 d[i]+=(1/6.0)*d[i+j]; 42 } 43 } 44 printf("%.4f\n",d[0]); 45 } 46 return 0; 47 }