• 【POJ】【3071】Football


    概率DP

      kuangbin总结中的第10题

      简单的画个比赛图,会发现是一颗完全二叉树,且同一层的子树之间各自独立,只有在合并得到更高一层结果时才结合。

      所以我们可以按比赛轮数进行DP,f[i][j]表示第 i 轮之后第 j 个球队没有被淘汰的概率,仔细一想可以发现:首先这支球队得在第 i-1 轮中胜出,然后他在第 i 轮中的对手的可能情况即是在比赛图二叉树中的「兄弟」结点代表的那2^(i-1)支球队,这个“兄弟”可以用异或快速求出。

      这样逐层递推,避免了许多无用的状态枚举,每层要枚举 2^i 支球队,以及第 i 支球队的2^(i-1)个可能的对手,所以复杂度为O(n* 2^2n)

     1 //POJ 3071
     2 #include<cmath>
     3 #include<cstdio>
     4 #define rep(i,n) for(int i=0;i<n;++i)
     5 #define F(i,j,n) for(int i=j;i<=n;++i)
     6 const int N=1<<8;
     7 double p[N][N],f[8][N];
     8 int main(){
     9 #ifndef ONLINE_JUDGE
    10     freopen("3071.in","r",stdin);
    11     freopen("3071.out","w",stdout);
    12 #endif
    13     int n,m;
    14     while(scanf("%d",&n)!=EOF && n!=-1){
    15         m=1<<n;
    16         rep(i,m) rep(j,m) scanf("%lf",&p[i][j]);
    17         
    18         rep(j,m) f[0][j]=1.0;
    19         F(i,1,n) rep(j,m){
    20             int t=j/(1<<(i-1));
    21             t^=1;
    22             f[i][j]=0;
    23             for(int k=t*(1<<(i-1)); k<t*(1<<(i-1))+(1<<(i-1));k++)
    24                 f[i][j]+=f[i-1][j]*f[i-1][k]*p[j][k];
    25         }
    26         int ans;
    27         double tmp=0;
    28         rep(i,m)
    29             if (f[n][i]>tmp){
    30                 ans=i;
    31                 tmp=f[n][i];
    32             }
    33         printf("%d
    ",ans+1);
    34     }
    35     return 0;
    36 }
    View Code
  • 相关阅读:
    Zabbix监控系统系列之二 : 初始化配置
    docker中的zabbix 配置钉钉机器人
    sqldbx 绿色小巧的数据库查询管理工具
    Windows 10 自建Anki 私有云服务器
    Sqlserver内存管理:限制最大占用内存
    tfs强制撤销其他工作区挂起更改,删除工作区
    easyui的一些文档
    IIS下日志分析
    zookeeper-client
    Windbg程序调试系列-索引篇(转)
  • 原文地址:https://www.cnblogs.com/Tunix/p/4302299.html
Copyright © 2020-2023  润新知