poj 3701 Football (概率+dp)

题目链接:http://poj.org/problem?id=3071

大致题意:共有2^n个球队,采用单向淘汰的形式进行比赛,即1队和2队进行1场比赛,3队和4队进行1场比赛,依次类推,胜者进入下一轮,比赛安排同上。这样只进行N轮就可以确定冠军。现在告诉你第i支球队战胜第j支球队的胜率矩阵,求最可能夺冠的队伍是哪支。

Time Limit: 1000MSMemory Limit: 65536K

样例:

Sample Input

2
0.0 0.1 0.2 0.3
0.9 0.0 0.4 0.5
0.8 0.6 0.0 0.6
0.7 0.5 0.4 0.0
-1

Sample Output

2

 

思路:题目下方给出的Hint基本就是题解:

              

所以很容易想到第i支球队在第j轮中获胜的概率应该是:


    dp[i][j]= ∑ dp[i][j-1]*dp[k][j-1]*Matrix[i][k]    k是第i支球队可能的对手

 

那么k的取值应该怎样找?首先第j轮,第i支球队可能的对手有2^(j-1)个,如果将比赛画成一颗树,2^n支球队是根节点,那么这2^(j-1)支球队就是i节点的兄弟节点所对应的所有根节点。

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 const int MAXNUM=150;
 5 double map[MAXNUM][MAXNUM];
 6 double dp[MAXNUM][10];
 7 int n;
 8 int main(){
 9     int i,j,k;
10     while(scanf("%d",&n)&&(n!=-1)){
11         memset(dp,0,sizeof(dp));
12         for(i=0;i<MAXNUM;i++)dp[i][0]=1;
13         int num=1<<n;  //共有2^n支队伍
14         for(i=0;i<num;i++){
15             for(j=0;j<num;j++){
16                 scanf("%lf",&map[i][j]);
17             }
18         }
19         for(j=1;j<=n;j++){
20             for(i=0;i<num;i++){
21                 int step=1<<(j-1);  //可能对手的个数
22                 int start=i/step;
23                 if(start%2)start--;  //寻找兄弟节点
24                 else start++;
25                 start*=step;
26                 for(k=start;k<start+step;k++){
27                     dp[i][j]+=dp[i][j-1]*dp[k][j-1]*map[i][k];
28                 }
29                 
30             }
31         }
32         double max=dp[0][n];
33         int win=0;
34         for(i=1;i<num;i++){
35             if(dp[i][n]>max){
36                 max=dp[i][n];
37                 win=i;
38             }
39         }
40         printf("%d\n",win+1);    
41     }
42     return 0;
43 }

 

 

 

posted @ 2012-07-30 10:36  McFlurry  阅读(194)  评论(0编辑  收藏  举报