HDU--4405(概率DP)
2014-12-30 11:35:57
思路:入门级概率DP。(虽然也写了挺久orz...)
其实就是个很简单的记忆化搜索 或者 递推,用dp[i]表示从 i 出发直至完成飞行需要的期望步数。
如果该点有flight line,那么dp[i] = dp[flight[i]],否则 dp[i] = (dp[i + k] + 1) / 6.0 (1<=k<=6)
1 #pragma comment(linker,"/STACK:1024000000,1024000000") 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <stack> 10 #include <queue> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 #define lp (p << 1) 15 #define rp (p << 1|1) 16 #define getmid(l,r) (l + (r - l) / 2) 17 #define MP(a,b) make_pair(a,b) 18 typedef long long ll; 19 typedef unsigned long long ull; 20 typedef pair<int,int> pii; 21 const int INF = 1 << 30; 22 23 int N,M; 24 double dp[100020]; 25 int vis[100020]; 26 27 double Solve(int p){ 28 if(dp[p]) return dp[p]; 29 if(p >= N) return 0.0; 30 if(vis[p]){ 31 dp[p] += Solve(vis[p]); 32 return dp[p]; 33 } 34 for(int i = 1; i <= 6; ++i) 35 dp[p] += (Solve(p + i) + 1.0) / 6.0; 36 return dp[p]; 37 } 38 39 int main(){ 40 int a,b; 41 while(scanf("%d%d",&N,&M) != EOF){ 42 if(N == 0 && M == 0) break; 43 memset(dp,0,sizeof(dp)); 44 memset(vis,0,sizeof(vis)); 45 for(int i = 1; i <= M; ++i){ 46 scanf("%d%d",&a,&b); 47 vis[a] = b; 48 } 49 Solve(0); 50 printf("%.4f\n",dp[0]); 51 } 52 return 0; 53 }