Discovering Gold LightOJ - 1030 || 概率與期望求法區別
阿新 • • 發佈:2017-10-28
targe cas get amp %d 通過 sum -i lightoj
1 #include<cstdio>//wrong_codes 2 #include<algorithm> 3 using namespace std; 4 double ans[110],anss; 5 int a[110],T,TT,n,endd; 6 int main() 7 { 8 int i,j; 9 scanf("%d",&T); 10 for(TT=1;TT<=T;TT++) 11 { 12 scanf("%d",&n); 13 for(i=1;i<=n;i++) 14 scanf("%d",&a[i]); 15 for(i=1;i<=n;i++) 16 ans[i]=0; 17 anss=0; 18 ans[1]=1; 19 for(i=1;i<=n;i++) 20 { 21 endd=n-i<6?n-i:6; 22 for(j=1;j<=endd;j++) 23 ans[i+j]+=ans[i]/endd;24 anss+=a[i]*ans[i]; 25 } 26 printf("Case %d: %.9lf\n",TT,anss); 27 } 28 return 0; 29 }
註意:雖然以上的代碼能通過,但是...下次還是不要用了。
代碼思路就是求出到達每一格的概率,然後每一格的金子乘上到達這一格的概率之和就是總期望。
但是,這樣做的時候會遇到很多難以理解的問題。比如以下一個看起來同樣有著合理的想法的方法:ans[i]表示到達i格拿到的金幣期望,再做一些很顯然的遞推。這個就是錯誤的。
順推的話,相比倒推,更容易出錯/遺漏/...。
1 #include<cstdio>//wrong_codes 2 #include<algorithm> 3 using namespace std; 4 double ans[110]; 5 int a[110],T,TT,n; 6 int main() 7 { 8 int i,j; 9 scanf("%d",&T); 10 for(TT=1;TT<=T;TT++) 11 { 12 scanf("%d",&n); 13 for(i=1;i<=n;i++) 14 scanf("%d",&a[i]); 15 for(i=1;i<=n;i++) 16 ans[i]=0; 17 ans[1]=a[1]; 18 for(i=2;i<=min(n,6);i++) 19 { 20 for(j=1;j<i;j++) 21 ans[i]+=ans[j]; 22 ans[i]/=(i-1); 23 ans[i]+=(double)a[i]; 24 } 25 for(i=min(n,6)+1;i<=n;i++) 26 { 27 for(j=1;j<=6;j++) 28 ans[i]+=ans[i-j]; 29 ans[i]/=6; 30 ans[i]+=(double)a[i]; 31 } 32 printf("Case %d: %.9lf\n",TT,ans[n]); 33 } 34 return 0; 35 }
正確的做法就是:概率正推,期望倒推。http://blog.csdn.net/nameofcsdn/article/details/52082746
ans[i]表示從i格出發得到gold的期望。ans[i]=sum{ans[i+p]}(1<=p<=6)+a[i]
Discovering Gold LightOJ - 1030 || 概率與期望求法區別