zoj 3605 Find the Marble
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4708
这题的dp还是不难想的,然后把状态转移时候的概率算上去就可以了
代码中有注释
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 using namespace std; 6 #define N 55 7 int a[N],b[N]; 8 double c[N][N]; //c[i][j] = i个里面取j个的取法 9 double dp[N][N][N]; //dp[i][j][l] 前i次操作看了j次在l位瓶子里面的概率 10 int main(){ 11 for(int i=0;i<=50;++i){ 12 c[i][0]=1; 13 for(int j=1;j<=i;++j) c[i][j]=c[i-1][j-1]+c[i-1][j]; 14 } 15 int T,m,n,k,s,t; 16 scanf("%d",&T); 17 while(T--){ 18 scanf("%d%d%d%d",&n,&m,&k,&s); 19 for(int i=1;i<=m;++i) scanf("%d%d",&a[i],&b[i]); 20 memset(dp,0,sizeof(dp)); 21 dp[0][0][s]=1; 22 for(int i=0;i<m;++i) for(int j=0;j<=i;++j) for(int l=1;l<=n;++l){ 23 dp[i+1][j][l]+=dp[i][j][l]*c[m-i-1][k-j]/c[m-i][k-j]; 24 if(a[i+1]==l) t=b[i+1]; 25 else if(b[i+1]==l) t=a[i+1]; 26 else t=l; 27 dp[i+1][j+1][t]+=dp[i][j][l]*c[m-i-1][k-j-1]/c[m-i][k-j]; 28 } 29 int ans=1; 30 for(int i=2;i<=n;++i) 31 if(dp[m][k][i]>dp[m][k][ans]) ans=i; 32 printf("%d\n",ans); 33 } 34 return 0; 35 }