Qiuqiqiu  
不管道路多么崎岖坎坷,我永远不停下追逐梦想的脚步!

hdu 2262 Where is the canteen http://acm.hdu.edu.cn/showproblem.php?pid=2262    2013-1-20

期望。每个点列出一个方程,高斯消元求解

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int N=20;
 7 const int dx[]={1,0,-1,0};
 8 const int dy[]={0,1,0,-1};
 9 const double eps=1e-8;
10 char mz[N][N];
11 double dp[N*N],mt[N*N][N*N],ans[N*N];
12 int dcmp(double x)
13 {
14     return x<-eps?-1:x>eps;
15 }
16 void getmt(int n,int m)
17 {
18     for(int x=0;x<n;x++)
19         for(int y=0;y<m;y++)
20         {
21             int r=x*m+y;
22             if(mz[x][y]=='#') continue;
23             if(mz[x][y]=='$') {mt[r][r]=1; continue;}
24             int cnt=0;
25             for(int d=0;d<4;d++)
26             {
27                 int nx=x+dx[d],ny=y+dy[d];
28                 if(nx>=0 && nx<n && ny>=0 && ny<m && mz[nx][ny]!='#') cnt++;
29             }
30             if(cnt>0)
31             {
32                 mt[r][r]=mt[r][n*m]=1;
33                 for(int d=0;d<4;d++)
34                 {
35                     int nx=x+dx[d],ny=y+dy[d];
36                     if(nx>=0 && nx<n && ny>=0 && ny<m && mz[nx][ny]!='#')
37                         mt[r][nx*m+ny]=-1.0/cnt;
38                 }
39             }
40         }
41 }
42 void gauss(int n,int m)
43 {
44     for(int r=0,c=0;r<n && c<m;r++,c++)
45     {
46         int p=r;
47         while(p<n && dcmp(mt[p][c])==0) p++;
48         if(p==n) {r--; continue;}
49         if(p!=r) for(int i=c;i<=m;i++)
50             swap(mt[p][i],mt[r][i]);
51         for(int i=0;i<n;i++)
52             if(i!=r && mt[i][c]!=0)
53             {
54                 double t=mt[i][c]/mt[r][c];
55                 for(int j=c;j<=m;j++)
56                     mt[i][j]-=mt[r][j]*t;
57             }
58     }
59     for(int i=0;i<n;i++)
60     {
61         int p=-1,cnt=0;
62         for(int j=i;j<m;j++) if(dcmp(mt[i][j])!=0)
63         {
64             p=j;
65             cnt++;
66         }
67         if(cnt==1) ans[p]=mt[i][m]/mt[i][p];
68     }
69 }
70 int main()
71 {
72     int n,m;
73     while(~scanf("%d%d",&n,&m))
74     {
75         for(int i=0;i<n;i++) scanf("%s",mz[i]);
76         memset(mt,0,sizeof(mt));
77         memset(ans,0,sizeof(ans));
78         getmt(n,m);
79         gauss(n*m,n*m);
80         double s;
81         for(int x=0;x<n;x++)
82             for(int y=0;y<m;y++)
83                 if(mz[x][y]=='@') s=ans[x*m+y];
84         if(dcmp(s)>0) printf("%lf\n",s);
85         else printf("-1\n");
86     }
87     return 0;
88 }

 

hdu 4089 Activation http://acm.hdu.edu.cn/showproblem.php?pid=4089    2013-1-19

求概率,跟求期望差不多,有环

求dp[i]时要把dp[i-1]看成常数

View Code
 1 #include <cstdio>
 2 using namespace std;
 3 
 4 const int N=2010;
 5 double dp[N][N],c[N];
 6 int main()
 7 {
 8     int n,m,k;
 9     double p1,p2,p3,p4;
10     while(~scanf("%d%d%d%lf%lf%lf%lf",&n,&m,&k,&p1,&p2,&p3,&p4))
11     {
12         if(1-p1-p2<1e-8)
13         {
14             printf("%.5lf\n",0);
15             continue;
16         }
17         dp[1][1]=p4/(1-p1-p2);
18         double q2=p2/(1-p1);
19         double q3=p3/(1-p1);
20         double q4=p4/(1-p1);
21         for(int i=2;i<=n;i++)
22         {
23             c[1]=q4;
24             for(int j=2;j<=i;j++)
25             {
26                 if(j<=k) c[j]=dp[i-1][j-1]*q3+q4;
27                 else c[j]=dp[i-1][j-1]*q3;
28             }
29             double sq=1,sc=0;
30             for(int j=2;j<=i;j++)
31             {
32                 sq=sq*q2;
33                 sc=sc*q2+c[j];
34             }
35             sq*=q2; sc=sc*q2+c[1];
36             dp[i][1]=sc/(1-sq);
37             for(int j=2;j<=i;j++)
38                 dp[i][j]=dp[i][j-1]*q2+c[j];
39         }
40         printf("%.5lf\n",dp[n][m]);
41     }
42     return 0;
43 }

 

hdu 3853 LOOPS http://acm.hdu.edu.cn/showproblem.php?pid=3853    2013-1-18

步数的期望

dp[i][j]=(dp[i][j+1]*p[i][j][1]+dp[i+1][j]*p[i][j][2]+dp[i][j]*p[i][j][0])+2

dp[i][j]=(dp[i][j+1]*p[i][j][1]+dp[i+1][j]*p[i][j][2]+2)/(1-p[i][j][0])

避免被0除,可能存在走不到p[i][j][0]=1的点

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int N=1010;
 6 const double INF=1e10;
 7 double dp[N][N],p[N][N][3];
 8 int main()
 9 {
10     int n,m;
11     while(~scanf("%d%d",&n,&m))
12     {
13         for(int i=1;i<=n;i++)
14             for(int j=1;j<=m;j++)
15                 for(int k=0;k<3;k++) scanf("%lf",&p[i][j][k]);
16         for(int i=n;i>0;i--)
17             for(int j=m;j>0;j--)
18             {
19                 if(i==n && j==m) dp[i][j]=0;
20                 else if(p[i][j][0]==1) dp[i][j]=INF;
21                 else dp[i][j]=(dp[i][j+1]*p[i][j][1]+dp[i+1][j]*p[i][j][2]+2)/(1-p[i][j][0]);
22             }
23         printf("%.3lf\n",dp[1][1]);
24     }
25     return 0;
26 }

 

hdu 4405 Aeroplane chess http://acm.hdu.edu.cn/showproblem.php?pid=4405    2013-1-18

步数的期望,0出发到n,掷骰子,几点走几步,中间有传送,求掷骰子次数的期望

n到n的期望为0,f(p)=sigma((f(p+k)+1)/6)

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int N=100010;
 6 double p[N];
 7 int next[N];
 8 int main()
 9 {
10     int n,m;
11     while(scanf("%d%d",&n,&m),n||m)
12     {
13         memset(next,-1,sizeof(next));
14         memset(p,0,sizeof(p));
15         for(int i=0;i<m;i++)
16         {
17             int u,v;
18             scanf("%d%d",&u,&v);
19             next[u]=v;
20         }
21         for(int u=n-1;u>=0;u--) if(next[u]==-1)
22         {
23             for(int i=1;i<=6;i++)
24             {
25                 int v=u+i;
26                 if(v>n) v=n;
27                 while(next[v]!=-1) v=next[v];
28                 p[u]+=(p[v]+1)/6;
29             }
30         }
31         printf("%.4lf\n",p[0]);
32     }
33     return 0;
34 }

 

hdu 4487 Maximum Random Walk http://acm.hdu.edu.cn/showproblem.php?pid=4487    2013-1-18

步数一定,求概率,虽然说是求期望,本质是先求各个状态的概率,再算期望

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const double eps=1e-8;
 6 const int N=110;
 7 double dp[N][N*2][N];
 8 int main()
 9 {
10     int T;
11     scanf("%d",&T);
12     while(T--)
13     {
14         int C;
15         scanf("%d",&C);
16         printf("%d ",C);
17         int n;
18         double pl,pr;
19         scanf("%d%lf%lf",&n,&pl,&pr);
20         memset(dp,0,sizeof(dp));
21         dp[0][n][n]=1;
22         for(int i=0;i<n;i++)
23             for(int j=0;j<=n*2;j++)
24                 for(int k=j;k<=n*2;k++) if(dp[i][j][k]>0)
25                 {
26                     dp[i+1][j][k]+=dp[i][j][k]*(1-pl-pr);
27                     dp[i+1][j-1][k]+=dp[i][j][k]*pl;
28                     if(j+1>k) dp[i+1][j+1][k+1]+=dp[i][j][k]*pr;
29                     else dp[i+1][j+1][k]+=dp[i][j][k]*pr;
30                 }
31         double ans=0;
32         for(int j=0;j<=n*2;j++)
33             for(int k=j;k<=n*2;k++) ans+=dp[n][j][k]*(k-n);
34         printf("%.4lf\n",ans);
35     }
36     return 0;
37 }

 

 

posted on 2013-01-17 23:40  Qiuqiqiu  阅读(518)  评论(0编辑  收藏  举报