概率练习 (16.04.30)
繼之前的概率dp,這次博文同樣和概率相關,但不僅僅限于dp處理。
UVA - 10288 Coupons
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1229
大意:買彩票,圖案有n種,如果收集到所有的n種彩票就能得到大獎。問平均情況下需要買多少張彩票?
分析:推狀態 ?
假設現在已經有了i種彩票,那么購買j的概率就是:
設 p=in,購買j次的概率就是 pj?1(1?p)
那么期望
那么結果就是 ∑i=0n?1nn?i #include <iostream> #include <cstdio> #include <cmath> using namespace std; typedef long long LL; LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b); } int main() {LL n;while(cin>>n){LL p1=n,p2=n,d;for(int i=1;i<n;i++){p1=p1*(n-i)+p2*n;p2=p2*(n-i);d=gcd(p1,p2);p1/=d; p2/=d;}LL ans=p1/p2;p1=p1-ans*p2;d=gcd(p1,p2);p1/=d; p2/=d;if(p1==0){printf("%lld\n",ans);continue;}LL len1=log10(ans)+1;for(int i=0;i<len1;i++) printf(" "); printf(" ");printf("%lld\n",p1);printf("%lld ",ans);LL len2=log10(p2)+1;for(int i=0;i<len2;i++) printf("-"); printf("\n");for(int i=0;i<len1;i++) printf(" "); printf(" ");printf("%lld\n",p2);}return 0; }
poj 3744 Scout YYF I
http://poj.org/problem?id=3744
大意:在一段路途中,給出N個地雷地點,一個人一次走1步或者2步,求解順利通過此路的概率。
分析:N很小,其數組元素ai很大,列出轉移式子,dp[i]=p×dp[i?1]+(1?p)×dp[i?2]
當然,我們沒有那么大的空間用于dp數組, 他只是假想存在的。
對于通過ai的概率就是
如果能夠順利通過,那么地雷點絕對是分界點!
分段:
1——x1
x1+1——x2
x2+1——x3
……
且到達x1+1,x2+1的概率是1!
hdu 5245 Joyful
http://acm.hdu.edu.cn/showproblem.php?pid=5245
大意:在棋盤中選兩個點作為子矩陣的對角線的點,該范圍內對格子圖色,問K次后涂色格子的方格期望。
分析:每次選擇A和B點這一事件是相互獨立的,且一個點可以多次重選。可以反著想,求出K次不被選中的概率,最后1減去它,就是選中的概率。
假設5區域的位置是一個格子(i,j),統計包含5的情況數:
當A在1時,B可以在5,6,8,9 (i-1)(j-1)(m-i+1)*(n-j+1);
A在2時,B可以在4,5,6,7,8,9 (i-1)1(m-i+1)*n;
3: (i-1)(n-j)(m-i+1)*j;
4: 1*(j-1)*(n-j+1)*m;
5: m*n
6: (n-j)*1*j*m;
7: (m-i)(j-1)*i(n-j+1);
8: (m-i)*1*i*n;
9: (m-i)*(n-j)*i*j;
最后一個格子被覆蓋的概率就是:1?(1?si,jm2n2)k
關于pow函數:
C++提供以下幾種pow函數的重載形式:
double pow(double X,int Y);
float pow(float X,float Y);
float pow(float X,int Y);
long double pow(long double X,long double Y);
long double pow(long double X,int Y);
靠! 當pow()的指數參數是浮點數時,運行效率很低。很容易超時。
但Y是整數時,利用分治遞歸可以提高效率。
自己寫函數替代pow(double, double):
#include <stdio.h> #include <math.h> #define LL long longint main() {//freopen("cin.txt","r",stdin);int t,ca=1;LL n,m,K;scanf("%d",&t);while(t--){scanf("%I64d%I64d%I64d",&m,&n,&K);double ans=0;for(LL i=1;i<=m;i++){for(LL j=1;j<=n;j++){double s=0.0;s+=(i-1)*(j-1)*(m-i+1)*(n-j+1);s+=(i-1)*1*(m-i+1)*n;s+=(i-1)*(n-j)*(m-i+1)*j; //3s+=1*(j-1)*(n-j+1)*m;s+=m*n;s+=(n-j)*1*j*m;s+=(m-i)*(j-1)*i*(n-j+1);s+=(m-i)*1*i*n;s+=(m-i)*(n-j)*i*j;s=s/m/m/n/n;//s=pow((1.0-s),1.0*K);double tt=1.0-s;s=1;for(int it=0;it<K;it++){s=s*tt;}ans=ans+1-s;}}LL res=ans+0.5;printf("Case #%d: %I64d\n",ca++,res);}return 0; }或者用C++的pow函數重載: pow(double, int) //不能用C寫,否則無法順利重載
#include <stdio.h> #include <math.h> #define LL long longint main() {//freopen("cin.txt","r",stdin);int t,ca=1;LL n,m;int K;scanf("%d",&t);while(t--){scanf("%I64d%I64d%d",&m,&n,&K);double ans=0;for(LL i=1;i<=m;i++){for(LL j=1;j<=n;j++){double s=0.0;s+=(i-1)*(j-1)*(m-i+1)*(n-j+1);s+=(i-1)*1*(m-i+1)*n;s+=(i-1)*(n-j)*(m-i+1)*j; //3s+=1*(j-1)*(n-j+1)*m;s+=m*n;s+=(n-j)*1*j*m;s+=(m-i)*(j-1)*i*(n-j+1);s+=(m-i)*1*i*n;s+=(m-i)*(n-j)*i*j;s=s/m/m/n/n;s=pow((1.0-s),K);/*double tt=1.0-s;s=1;for(int it=0;it<K;it++){s=s*tt;}*/ans=ans+1-s;}}LL res=ans+0.5;printf("Case #%d: %I64d\n",ca++,res);}return 0; }效率對比:
acdream 1113 The Arrow
http://acdream.info/problem?pid=1113
大意:一個人扔色子,每次將點數相加,如果大于N,保證點數和不變,否則加上得到的點數,問擲色子的次數的期望。
分析:如果是”>=N”的類型問題,應該是dp[i]=∑(16dp[i+j])+1
對于這種”==N”的類型問題,dp[i]=k×dp[i]16+∑(dp[i+j]16)+1
化簡得到: dp[i]=66?k(∑dp[i+j]16+1)
總結
以上是生活随笔為你收集整理的概率练习 (16.04.30)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务器性能测试--super PI 测试
- 下一篇: 单片机设计一个十字路口交通灯模拟控制系统