概率dp 期望 逆推
题目大意:
从起点0点开始到达点n,通过每次掷色子前进,可扔出1,2,3,4,5,6这6种情况,扔到几前进几,当然对应飞行通道可以通过x直达一点y,x<y,计算到达n点或超过n
点要扔色子的次数的数学期望
从某一点 i 扔完色子可到达 i+1,i+2,i+3,i+4,i+5,i+6这6个点,令dp[i]为到达末尾的数学期望
那么到达之后6个点的数学期望是一样的,那么dp[i]=dp[i+1]*1/6.0+dp[i+2]*1/6.0+dp[i+3]*1/6.0+dp[i+4]*1/6.0+dp[i+5]*1/6.0+dp[i+6]*1/6.0+1
碰到可以直接飞的进行一个if判断,直接将dp值赋予即可,不执行上述的dp操作过程
1 #include<cstdio> 2 #include<algorithm> 3 #include<math.h> 4 #include<string.h> 5 using namespace std; 6 const int maxn=1e5+10; 7 int match[maxn]; 8 double dp[maxn]; 9 void init() 10 { 11 memset(dp,0,sizeof(dp)); 12 memset(match,0,sizeof(match)); 13 } 14 int main() 15 { 16 int n,m; 17 while(scanf("%d%d",&n,&m)!=EOF){ 18 if(n==0&&m==0) break; 19 init(); 20 for(int i=1;i<=m;i++){ 21 int a,b; 22 scanf("%d%d",&a,&b); 23 match[a]=b; 24 } 25 for(int i=n-1;i>=0;i--){ 26 if(match[i]) dp[i]=dp[match[i]]; 27 else{ 28 for(int j=1;j<=6;j++){ 29 dp[i]+=dp[j+i]/6.0; 30 } 31 dp[i]+=1; 32 } 33 } 34 printf("%.4f\n",dp[0]); 35 } 36 return 0; 37 }