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 }

你可能感兴趣的:(find)