light oj 1151 - Snakes and Ladders 高斯消元+概率DP
思路:
在没有梯子与蛇的时候很容易想到如下公式:
dp[i]=1+(∑dp[i+j])/6
但是现在有梯子和蛇也是一样的,初始化p[i]=i;
当有梯子或蛇时转移为p[a]=b;
这样方程变为:
dp[i]=1+(∑dp[p[i+j]])/6
再就是注意当i+j>100时,停在原地不变。
代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define M 105 7 #define eps 1e-6 8 using namespace std; 9 double ans[M],an[M][M]; 10 int p[M]; 11 void GAUSS() 12 { 13 int i,j,t,k; 14 for(i=1;i<=100;i++){ 15 t=i; 16 for(j=i+1;j<=100;j++) 17 if(an[t][i]<an[j][i]) t=j; 18 if(t!=i){ 19 for(j=1;j<=101;j++) 20 swap(an[i][j],an[t][j]); 21 } 22 if(fabs(an[i][i])<eps) continue; 23 for(j=i+1;j<=100;j++){ 24 if(fabs(an[j][i])>eps){ 25 double tt=an[j][i]/an[i][i]; 26 for(k=i;k<=101;k++) 27 an[j][k]=an[j][k]-an[i][k]*tt; 28 } 29 } 30 } 31 for(i=100;i>=1;i--){ 32 for(j=100;j>i;j--){ 33 an[i][101]-=an[i][j]*ans[j]; 34 } 35 if(fabs(an[i][i])>eps) 36 ans[i]=an[i][101]/an[i][i]; 37 if(fabs(ans[i])<eps) ans[i]=0.0; 38 } 39 } 40 void solve() 41 { 42 memset(ans,0,sizeof(ans)); 43 memset(an,0,sizeof(an)); 44 for(int i=1;i<=100;i++){ 45 an[i][i]=an[i][101]=6.0; 46 for(int j=1;j<=6;j++){ 47 if(i+j>100) an[i][i]-=1.0; 48 else an[i][p[i+j]]+=-1.0; //感开始没有+,一直错啊………… 49 } 50 } 51 GAUSS(); 52 } 53 int main() 54 { 55 int t,ca=0,n,m,a,b; 56 scanf("%d",&t); 57 while(t--){ 58 scanf("%d",&n); 59 for(int i=1;i<=100;i++) p[i]=i; 60 for(int i=0;i<n;i++){ 61 scanf("%d %d",&a,&b); 62 p[a]=b; 63 } 64 solve(); 65 printf("Case %d: %.8lf\n",++ca,ans[1]); 66 } 67 return 0; 68 }