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

题意:

  给定n,有2^n支队伍参加足球赛。

  给你所有的p[i][j],表示队伍i打败队伍j的概率。

  淘汰赛制。第一轮(1,2)两队比、(3,4)比、(5,6)比...共进行n轮比赛后产生冠军。

  问你冠军最有可能是哪支队伍。

题解:

  表示状态:

    dp[i][j] = probability to win

    第i支队伍能够参加第j轮比赛的概率。

  找出答案:

    i of max dp[i][n+1]

    n轮比赛后,冠军该参加第n+1轮比赛(不存在的)。

  如何转移:

    now: dp[i][j]

    dp[i][j+1] = ∑ (dp[i][j] * dp[k][j] * p[i][k]) (加法原理)

    k: 第j轮比赛和i比的队伍

    P(i晋级到j+1轮) = ∑ (P(i晋级到j轮) * P(k晋级到j轮) * P(i打败k))

    怎样枚举k:

      将所有队伍从0开始编号,并用二进制表示。

      第i支战队第j轮会碰到的对手是:将i化为二进制,从右往左开始算,第j-1位会不同,第j位开始要相同,其余位任意的所有数。

  边界条件:

    dp[i][1] = 1
    others = 0

  注:本题居然卡cin。。。 (*`皿´*)ノ

AC Code:

 // state expression:
// dp[i][j] = probability to win
// i: which team
// j: which round
//
// find the answer:
// i of max dp[i][n+1]
//
// transferring:
// dp[i][j+1] = sigma (dp[i][j] * dp[k][j] * p[i][k])
// 0<=t<(1<<(j-1))
// k = (((i>>(j-1))^1)<<(j-1))|t
//
// boundary:
// dp[i][1] = 1
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 10
#define MAX_T 150 using namespace std; int n;
int ans;
double p[MAX_T][MAX_T];
double dp[MAX_T][MAX_N]; void read()
{
for(int i=;i<(<<n);i++)
{
for(int j=;j<(<<n);j++)
{
scanf("%lf",&p[i][j]);
}
}
} void solve()
{
memset(dp,,sizeof(dp));
for(int i=;i<(<<n);i++)
{
dp[i][]=;
}
for(int j=;j<=n;j++)
{
for(int i=;i<(<<n);i++)
{
for(int t=;t<(<<(j-));t++)
{
int k=((((i>>(j-))^)<<(j-))|t);
dp[i][j+]+=dp[i][j]*dp[k][j]*p[i][k];
}
}
}
double maxn=;
for(int i=;i<(<<n);i++)
{
if(dp[i][n+]>maxn)
{
maxn=dp[i][n+];
ans=i+;
}
}
} void print()
{
printf("%d\n",ans);
} int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==-) break;
read();
solve();
print();
}
}

POJ 3071 Football:概率dp的更多相关文章

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

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

  2. POJ 3071 Football(概率DP)

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

  3. poj 3071 Football(概率dp)

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

  4. POJ 3071 Football (概率DP)

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

  5. POJ 3071 Football

    很久以前就见过的...最基本的概率DP...除法配合位运算可以很容易的判断下一场要和谁比.    from——Dinic算法                         Football Time ...

  6. POJ3071:Football(概率DP)

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

  7. POJ 3156 - Interconnect (概率DP+hash)

    题意:给一个图,有些点之间已经连边,现在给每对点之间加边的概率是相同的,问使得整个图连通,加边条数的期望是多少. 此题可以用概率DP+并查集+hash来做. 用dp(i,j,k...)表示当前的每个联 ...

  8. poj 1322 Chocolate (概率dp)

    ///有c种不同颜色的巧克力.一个个的取.当发现有同样的颜色的就吃掉.去了n个后.到最后还剩m个的概率 ///dp[i][j]表示取了i个还剩j个的概率 ///当m+n为奇时,概率为0 # inclu ...

  9. [poj3071]football概率dp

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

随机推荐

  1. 【C语言天天练(十一)】深入理解指针

    引言:在C语言中.指针的地位是不言而喻的,要想非常好的掌握C语言,掌握指针是必须的,这也是C语言不同于其它语言的地方. (一)指针的指针 样例: int i; int *pi;/*把pi初始化为指向变 ...

  2. vue2 axios 接口函数封装

    封装 axios 工具,编辑 src/api/index.js 文件 首先,我们要使用 axios 工具,就必须先安装 axios 工具.执行下面的命令进行安装 npm install axios - ...

  3. vue.js+koa2项目实战(一)创建项目和elementUI配置

    前端采用vuex+element-ui: 后端采用koa2+restfulAPI+sequlize: (一)项目介绍 宠物社区 1.社区 2.好友 3.说说 4.宠粮 5.健康 (二)项目框架 1.V ...

  4. Python例子二

    例1.构造函数 #-*-coding:utf--*- import sys class Student: def __init__(self,name,age): self.__name=name s ...

  5. vuex 深入理解

    参考自:https://mp.weixin.qq.com/s?src=11&timestamp=1528275978&ver=922&signature=ZeHPZ2ZrLir ...

  6. apue学习笔记(第四章 文件和目录)

    本章将描述文件系统的其他特性和文件的性质. 函数stat.fstat.fstatat和lstat #include <sys/stat.h> int stat(const char *re ...

  7. Archlinux休眠设置

    2017-03-11 更新: 优化部分文字描述; 默认情况下禁用 swap 分区, 当执行休眠操作时先启用 swap 分区, 然后再执行休眠操作(给 /usr/bin/{swapon,swapoff} ...

  8. css:颜色名和十六进制数值

    http://www.w3school.com.cn/cssref/css_colornames.asp

  9. Android · 获取网络图片

    import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import j ...

  10. 3、C++新的关键字

        C++ 添加了一些全新的关键字. 1.new     new 来进行动态内存的分配,而delect 则是进行内存的释放, 申请的方式: 变量申请: int *p = new int; // 申 ...