poj1189

题意:在一块木板上,钉上钉子,排布成等边三角形。一个球从顶部开始,自由下落。每碰到一个钉子以后,等概率地向两边继续滚。现从该等边三角形的钉子中,拔去其中某些钉子。求这个球从顶部开始下落,滚到底部某个格子的概率。
思路:DP模拟。逐步递推,分别计算每一层,滚到每一个口的概率。最后一层每个口的概率,就是对应底部每个格子的概率。每一个口的概率,若遇到一个钉子,则除以2后就是下一层对应两个口的概率;若没遇到钉子,则直接等于再下层的对应入口,即直接落下。一开始的初值,就是2^层数,即全部都是钉子时,第一个格子对应的概率。
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 using namespace std;
 5 
 6 __int64 gcd(__int64 a  ,  __int64 b)
 7 {
 8     return b==0?a:gcd(b,a%b);
 9 }
10 __int64 dp[55][55];
11 char map[55][55];
12 char s[55];
13 int main()
14 {
15     int m,n;
16     cin>>n>>m;
17     for(int i=1;i<=n;i++)//因为空格可以无限多个,所以最好当做字符串来输入
18     {
19         for(int j=1;j<=i;j++)
20         {
21             cin>>s;
22             map[i][j]=s[0];
23         }
24     }
25     dp[1][1]=1ll<<n;
26     //cout<<"Only use to test :"<<dp[1][1]<<endl;
27     for(int i=1;i<=n;i++)
28     {
29         for(int j=1;j<=i;j++)
30         {
31             if(map[i][j]=='*')
32             {
33                 dp[i+1][j]+=dp[i][j]>>1;
34                 dp[i+1][j+1]+=dp[i][j]>>1;
35             }
36             else
37             {
38                 dp[i+2][j+1]+=dp[i][j];
39             }
40         }
41     }
42     __int64 ans=dp[n+1][m+1];
43     __int64 sum=0;
44     for(int i=1;i<=n+1;i++)
45     {
46         sum+=dp[n+1][i];
47     }
48     __int64 k;
49     k=gcd(sum,ans);
50     printf("%I64d/%I64d\n",ans/k,sum/k);
51     return 0;
52 }

其中出现了一个小错误害了我找了半天的错误,结果出在

 dp[1][1]=1<<n;这句上,数字1会默认是int型的所以要1ll<<n,这样就可以AC了

posted on 2012-08-18 10:31  矮人狙击手!  阅读(559)  评论(0编辑  收藏  举报

导航