2017寒假機率dp訓練題

poj 3744 Scout YYF I    php

簡單題,不難找到遞推,設dp[i]爲安全達到i的機率,dp[0]=0,dp[1]=1,dp[i]=p*dp[i-1]+(1-p)*dp[i-2],用矩陣快速冪計算,再相乘.安全

代碼:ide

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int N;double p;
 6 int a[15];
 7 struct matrix{
 8     double a[2][2];
 9 };
10 matrix muti(matrix x,matrix y){
11     matrix t;
12     for(int i=0;i<2;++i){
13         for(int j=0;j<2;++j){
14             t.a[i][j]=0;//init
15             for(int k=0;k<2;++k){
16                 t.a[i][j]+=1.0*x.a[i][k]*y.a[k][j];
17             }
18         }
19     }
20     return t;
21 }
22 double getP(int n){
23     matrix ans,base;
24     ans.a[0][0]=1;ans.a[0][1]=ans.a[1][0]=ans.a[1][1]=0;
25     base.a[0][0]=p;base.a[0][1]=1-p;base.a[1][0]=1.0;base.a[1][1]=0.0;
26     if(n<0)return 0;
27     while(n){
28     //    printf("n=%d\n",n);
29         if(n&1)ans=muti(base,ans);
30         base=muti(base,base);
31         n/=2;
32     }
33     return ans.a[0][0];
34 }
35 int main(){
36     while(~scanf("%d%lf",&N,&p)){
37         for(int i=0;i<N;++i){
38             scanf("%d",&a[i]);
39         }
40         sort(a,a+N);
41         double res=1.0;
42         int prev=1;
43         for(int i=0;i<N;++i){
44             res=res*(1-p)*getP(a[i]-prev-1);
45             prev=a[i]+1;
46         }
47         printf("%.7f\n",res);
48     }
49     return 0;
50 }
View Code

 cf148Dspa

題目連接:http://codeforces.com/problemset/problem/148/D3d

簡單題,我是寫的記憶化搜索,但開始在巨龍的公式那出了問題,花了兩個多小時.code

代碼:blog

 1 #include<cstdio>
 2 #include<cstring>
 3 const int MAXN=1007;
 4 double dp[MAXN][MAXN][2];
 5 int visit[MAXN][MAXN][2];
 6 //0 is princess,1 is dragon
 7 double dfs(int w,int b,int status){
 8     //printf("w=%d,b=%d,status=%d\n",w,b,status);
 9     if(w<=0){
10          dp[0][b][1]=1.0;
11          dp[0][b][0]=0.0;
12          return dp[0][b][status];
13     }
14     if(b<=0){
15         dp[w][0][status]=1.0;
16         dp[w][0][1-status]=0.0;
17         return dp[w][0][status];
18     }
19     if(visit[w][b][status])return dp[w][b][status];
20     visit[w][b][status]=1;
21     double res=w*1.0/(w+b);
22     if(status==0){
23         res+=b*1.0/(w+b)* (1.0-dfs(w,b-1,1));
24     }else{
25         res+=b*1.0/(w+b)* (((w*1.0/(w+b-1)*(1-dfs(w-1,b-1,0)))) + ((b-1)*1.0/(w+b-1)*(1-dfs(w,b-2,0))));
26     }
27     dp[w][b][status]=res;
28     //printf("dp[%d][%d][%d]=%.9f\n",w,b,status,res);
29     return dp[w][b][status];
30 }
31 int main(){
32     int w,b;
33     scanf("%d%d",&w,&b);
34     memset(visit,0,sizeof(visit));
35     printf("%.10f\n",dfs(w,b,0));
36     return 0;
37 }
View Code

 hdoj4405 飛行棋get

題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=4405string

指望入門題,問達到終點指望投多少次骰子.it

代碼:

 1 #include<cstdio>
 2 #include<cstring>
 3 const int MAXN=2e5+7,MAXM=1e3+7;
 4 double dp[MAXN];
 5 int fly[MAXN];
 6 int main(){
 7     int N,M;
 8     while(scanf("%d%d",&N,&M)&&N+M){
 9         memset(fly,0,sizeof(fly));
10         memset(dp,0,sizeof(dp));
11         for(int i=0;i<M;++i){
12             int a,b;scanf("%d%d",&a,&b);
13             fly[a]=b;
14         }
15         dp[N]=0;
16         for(int i=N-1;i>=0;--i){
17             if(fly[i]==0){
18                 for(int x=1;x<=6;++x){
19                     dp[i]+=1.0/6*dp[i+x];
20                 }
21                 dp[i]++;
22             }
23             else dp[i]=dp[fly[i]];
24         }
25         printf("%.4f\n",dp[0]);
26     }
27     return 0;
28 }
View Code
相關文章
相關標籤/搜索