直接上状态转移方程:

记dp[i][j]为第i轮比赛,第j个队伍获胜的概率。

那么初始状态下,dp[0][j]=1;//也就是第0轮比赛全都获胜

d[i][j]=sum(d[i-1][j]*d[i-1][k]*win[j][k])//也就是找到所有可能与j队在第i轮对决的k队,那么i队战胜k队的概率为 :第i-1轮第j队出线的概率*第i-1轮第k支队伍出现的概率*第i轮j队打败k队的概率。将所有的k的可能取值都遍历一遍求概率和,所得结果就是d[i][j]。

其中,如何找到所有可能的k队是一个难点。

一般想法是先进行分组:

例如共8支队伍

第一轮中分组为(1,2)(3,4)(5,6)(7,8)

第二轮中分组为((1|2),(3|4))((5|6),(7|8))

因此不妨先按组号进行划分:

第一轮第1组组员有1,2;第2组有3,4;第3组有5,6;第四组有7,8;

观察可发现 组号=(队号-1)>>1;

同样的在第二轮中 组号=(队号-1)>>2;

那么第n轮中 组号=(队号-1)>>n;

分完组只是第一步。

接下来我们知道,只有组号为相邻的两个数的队伍才可能比赛(而且这个相邻是有序的,必须满足(a,a+1)其中a为奇数)

这里应该可以按照奇偶性来判断,不过我没有尝试。而是用了另一个更简便的技巧:用异或运算来判断相邻。(异或完美的适配题目要求的这种相邻,具体见程序)

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
double win[][];
double dp[][];
int main(void){
int n;
while(scanf("%d",&n)==&&n!=-){
memset(dp,,sizeof(dp)) ;
int len=<<n;
for(int i=;i<=len;i++){
for(int j=;j<=len;j++)
scanf("%lf",&win[i][j]);
}
for(int i=;i<=len;i++){//初始化
dp[][i]=;
}
for(int i=;i<=n;i++){
for(int j=;j<=len;j++){
//自己想,怎么判断能比赛
for(int k=;k<=len;k++) {
if(((k-)>>(i-))==(((j-)>>(i-))^)){//优先级 链接:https://blog.csdn.net/u013630349/article/details/47444939
//位移运算相当于在进行分组,异或运算则是判断相邻,而且这个相邻是正好满足题目条件的有规律的相邻 ,可以写几个数试一下。
dp[i][j]+=dp[i-][j]*dp[i-][k]*win[j][k];
}
}
}
}
double max=dp[n][];
int ans=;
for(int i=;i<=len;i++){
if(dp[n][i]>max){
max=dp[n][i];
ans=i;
}
}
printf("%d\n",ans);
}
return ;
}

poj_3071 Football(概率dp)的更多相关文章

  1. POJ3071:Football(概率DP)

    Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, …, 2 ...

  2. [poj3071]football概率dp

    题意:n支队伍两两进行比赛,求最有可能获得冠军的队伍. 解题关键:概率dp,转移方程:$dp[i][j] +  = dp[i][j]*dp[i][k]*p[j][k]$表示第$i$回合$j$获胜的概率 ...

  3. poj 3071 Football (概率DP水题)

    G - Football Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit ...

  4. POJ 3071 Football(概率DP)

    题目链接 不1Y都对不住看过那么多年的球.dp[i][j]表示i队进入第j轮的概率,此题用0-1<<n表示非常方便. #include <cstdio> #include &l ...

  5. Football 概率DP poj3071

                                                                                                 Footbal ...

  6. POJ3071 Football 概率DP 简单

    http://poj.org/problem?id=3071 题意:有2^n个队伍,给出每两个队伍之间的胜率,进行每轮淘汰数为队伍数/2的淘汰赛(每次比赛都是相邻两个队伍进行),问哪只队伍成为冠军概率 ...

  7. poj 3071 Football(概率dp)

    id=3071">http://poj.org/problem? id=3071 大致题意:有2^n个足球队分成n组打比赛.给出一个矩阵a[][],a[i][j]表示i队赢得j队的概率 ...

  8. POJ 3071 Football (概率DP)

    概率dp的典型题.用dp[j][i]表示第j个队第i场赢的概率.那么这场要赢就必须前一场赢了而且这一场战胜了可能的对手.这些都好想,关键是怎么找出当前要算的队伍的所有可能的竞争对手?这个用异或来算,从 ...

  9. [转]概率DP总结 by kuangbin

    概率类题目一直比较弱,准备把kuangbin大师傅总结的这篇题刷一下! 我把下面的代码换成了自己的代码! 原文地址:http://www.cnblogs.com/kuangbin/archive/20 ...

  10. 【POJ 3071】 Football(DP)

    [POJ 3071] Football(DP) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4350   Accepted ...

随机推荐

  1. JZOJ.5329【NOIP2017模拟8.22】时间机器

    Description

  2. WEB安全番外第六篇--关于通过记录渗透工具的Payload来总结和学习测试用例

    背景: 在WEB安全的学习过程中,了解过了原理之后,就是学习各种Payload,这里面蕴藏着丰富的知识含量,是在基本上覆盖了漏洞原理之后的进一步深入学习的必经之路.无理是Burpsuite还是Sqlm ...

  3. Swift - 点击箭头旋转

    let arrowImage = UIImageView(image: UIImage(named: "Machine_arrow")!.imageWithRenderingMod ...

  4. mysql 把表中某一列的内容合并为一行

    1,把表中某一列的内容合并为一行 select province,CONCAT('[\"全部\",\"',GROUP_CONCAT(city ORDER BY cityI ...

  5. MySQL逗号分割字段的列转行

    前言: 由于很多业务表因为历史原因或者性能原因,都使用了违反第一范式的设计模式.即同一个列中存储了多个属性值(具体结构见下表). 这种模式下,应用常常需要将这个列依据分隔符进行分割,并得到列转行的结果 ...

  6. 深究AngularJS——自定义服务详解(factory、service、provider)

    前言 3种创建自定义服务的方式.  Factory Service Provider 大家应该知道,AngularJS是后台人员在工作之余发明的,他主要应用了后台早就存在的分层思想.所以我们得了解下分 ...

  7. C#桌面程序设计复习

    GGG //屏幕高度 int ScreenH = 1080; this.Location = new Point(this.Location.X, ScreenH - this.Height - 20 ...

  8. nginx:负载均衡的session共享

    一.场景 当nginx做了负载均衡之后,同一个ip的url请求服务器的时候,负载均衡会根据每台服务器的权重等一些设置将请求转发到不同的服务器上去进行处理,这样的话针对一些带有状态请求的情况来说就是个很 ...

  9. django的request对象和response对象

    概述Django 使用 request 和 response 对象表示系统状态数据..当请求一个页面时,Django创建一个 HttpRequest 对象.该对象包含 request 的元数据. 然后 ...

  10. python获取当天日期进行格式转换

    # Python Library import time def getToday(format=3): """返回今天的日期字串""" # ...