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了