卧薪尝胆,厚积薄发。
Football
Date: Thu Sep 06 18:50:34 CST 2018 In Category: NoCategory

Description:

给 $2^n$ 个球队淘汰赛,问最后哪个球队赢得比赛的概率最大。
$1\le n \le 7$

Solution:

$f[k][l][r]$ 表示 $k$ 在 $l$ 和 $r$ 这个区间中胜出的概率,发现只有 $r=2^k$ , $l=2^k+1$ 的状态有用,于是记忆化搜索。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n;
#define MAXN 8
double p[1 << MAXN][1 << MAXN];
double f[1 << MAXN][1 << MAXN][1 << MAXN];
bool vis[1 << MAXN][1 << MAXN][1 << MAXN];
double dp(int k,int l,int r)
{
if(l == r)return 1;
if(vis[k][l][r])return f[k][l][r];
int mid = ((l + r) >> 1);
double res = 0;
if(k <= mid)
{
for(int i = mid + 1;i <= r;++i)
{
res += dp(i,mid + 1,r) * p[k][i];
}
res = res * dp(k,l,mid);
}
else
{
for(int i = l;i <= mid;++i)
{
res += dp(i,l,mid) * p[k][i];
}
res = res * dp(k,mid + 1,r);
}
vis[k][l][r] = true;
f[k][l][r] = res;
return res;
}
int main()
{
while(scanf("%d",&n) && n != -1)
{
memset(vis,false,sizeof(vis));
for(int i = 1;i <= (1 << n);++i)
for(int j = 1;j <= (1 << n);++j)
scanf("%lf",&p[i][j]);
double ans1 = 0.0;
int ans2 = 0;
for(int i = 1;i <= (1 << n);++i)
{
if(dp(i,1,(1 << n)) > ans1)
{
ans1 = dp(i,1,(1 << n));
ans2 = i;
}
}
printf("%d\n",ans2);
}
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡