ZOJ 3605Find the Marble(dp)

ZOJ 3605

大体意思就是 找出随机选了K个交换后 石子在第i个罐子里的概率最大 

也就是可能的总数最大 这样就可以写出递推方程 dp[i][j][k] += dp[i-1][e][k]; (0<e<j&& k!=a[j]&&k!=b[j]) dp[i][j][a[j]]+=dp[i-1][e][b[j]] dp[i][j][b[j]]+=dp[i-1][e][a[j]];

 dp[i][j][k]表示选第i次交换时 选的为第j个 而且石子在第K个罐子里的可能 这样有两种可能 1:石子在a[j]或b[j]中 也就是要交换的两个罐头里 那么可能数就交换相加,然后再加别的。

要么是不在 那么就加上上一步的可能总数 。

 

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 100000
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 LL dp[55][55][55],sum[55];
18 int a[55],b[55];
19 int main()
20 {
21     int s,g,e,t,i,j,k,n,m;
22     cin>>t;
23     while(t--)
24     {
25         cin>>n>>m>>k>>s;
26         memset(dp,0,sizeof(dp));
27         memset(sum,0,sizeof(sum));
28         for(i =1; i <= m ;i++)
29         {
30             cin>>a[i]>>b[i];
31             if(a[i]==s)
32             dp[1][i][b[i]] = 1;
33             else if(b[i]==s)
34             dp[1][i][a[i]] = 1;
35             else
36             dp[1][i][s] = 1;
37         }
38         for(i = 2 ; i<= k ;i++)
39             for(j = i; j <= m ;j++)
40             {
41                 for(e = i-1 ; e < j; e++)
42                 {
43                     if(a[j]!=b[j])
44                     {
45                         dp[i][j][a[j]]+=dp[i-1][e][b[j]];
46                         dp[i][j][b[j]]+=dp[i-1][e][a[j]];
47                     }
48                     else
49                     dp[i][j][a[j]] += dp[i-1][e][a[j]];
50                     for(g = 1; g <= n ;g++)
51                     {
52                         if(g==a[j]) continue;
53                         if(g==b[j]) continue;
54                         dp[i][j][g]+=dp[i-1][e][g];
55                     }
56                 }
57             }
58         LL maxz=0;
59         int ans = s;
60         for(i = k; i <= m ; i++)
61         {
62             for(j = 1; j <= n ; j++)
63             {
64                 sum[j]+=dp[k][i][j];
65             }
66         }
67         for(i = 1; i <= n ;i++)
68         {
69             if(maxz<sum[i])
70             {
71                 ans = i;
72                 maxz = sum[i];
73             }
74         }
75         cout<<ans<<endl;
76     }
77     return 0;
78 }
View Code

 

posted @ 2014-03-08 21:39  _雨  阅读(395)  评论(0编辑  收藏  举报