CodeForces-859D Third Month Insanity(期望DP)

D. Third Month Insanity

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

The annual college sports-ball tournament is approaching, which for trademark reasons we'll refer to as Third Month Insanity. There are a total of 2N teams participating in the tournament, numbered from 1 to 2N. The tournament lasts N rounds, with each round eliminating half the teams. The first round consists of 2N - 1 games, numbered starting from 1. In game i, team 2·i - 1 will play against team 2·i. The loser is eliminated and the winner advances to the next round (there are no ties). Each subsequent round has half as many games as the previous round, and in game i the winner of the previous round's game 2·i - 1 will play against the winner of the previous round's game 2·i.

Every year the office has a pool to see who can create the best bracket. A bracket is a set of winner predictions for every game. For games in the first round you may predict either team to win, but for games in later rounds the winner you predict must also be predicted as a winner in the previous round. Note that the bracket is fully constructed before any games are actually played. Correct predictions in the first round are worth 1 point, and correct predictions in each subsequent round are worth twice as many points as the previous, so correct predictions in the final game are worth 2N - 1 points.

For every pair of teams in the league, you have estimated the probability of each team winning if they play against each other. Now you want to construct a bracket with the maximum possible expected score.

Input

Input will begin with a line containing N (2 ≤ N ≤ 6).

2N lines follow, each with 2N integers. The j-th column of the i-th row indicates the percentage chance that team i will defeat team j, unless i = j, in which case the value will be 0. It is guaranteed that the i-th column of the j-th row plus the j-th column of the i-th row will add to exactly 100.

Output

Print the maximum possible expected score over all possible brackets. Your answer must be correct to within an absolute or relative error of 10 - 9.

Formally, let your answer be a, and the jury's answer be b. Your answer will be considered correct, if .

Examples

input

2
0 40 100 100
60 0 40 40
0 60 0 45
0 60 55 0

output

1.75

input

3
0 0 100 0 100 0 0 0
100 0 100 0 0 0 100 100
0 0 0 100 100 0 0 0
100 100 0 0 0 0 100 100
0 100 0 100 0 0 100 0
100 100 100 100 100 0 0 0
100 0 100 0 0 100 0 0
100 0 100 0 100 100 100 0

output

12

input

2
0 21 41 26
79 0 97 33
59 3 0 91
74 67 9 0

output

3.141592

Note

In the first example, you should predict teams 1 and 4 to win in round 1, and team 1 to win in round 2. Recall that the winner you predict in round 2 must also be predicted as a winner in round 1.

题意:有2^{n}个人参加比赛,第一轮2*i-1和2*i进行比赛,胜者参加下一轮,编号为i,每一轮重新编号后都是由2*i-1和2*i进行比赛,每个人对其他人都有一个胜率。现在要进行下注,即每一场比赛之前都竞猜该比赛的胜者,要求这一轮下注的选手必须在上一轮也被下注,如果在第i轮竞猜正确则获得2^{i-1}积分,要求选取一种下注方式,使得获得的积分期望值最高,输出这个期望值。

题解:期望dp

设wr(i,x)为x一直获胜到第i轮的概率,a(x,y)为x赢y的概率

f(i,x,y)表示第i轮x与y进行比赛,并且下注x获胜,得到的积分的期望

dp(i,x)表示到第i轮为止,下注x获胜,获得的总积分的期望

f(i,x,y)=a(x,y)*wr(i-1,x) * wr(i-1,y) * 2^{i-1}

dp(i,x) = dp(i-1,x) + max_{y} (dp(i-1,y)) + \sum_{y=1}^{2^{n}} f(i,x,y)

#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define x first
#define y second
#define rep(i,a,b) for(int i=a;i<(b);++i)
#define per(i,a,b) for(int i=a-1;i>=(b);--i)
#define fuck(x) cout<<'['<<#x<<' '<<(x)<<']'
#define add(x,y) x=((x)+(y)>=mod)?(x)+(y)-mod:(x)+(y)
#define sub(x,y) x=((x)-(y)<0)?(x)-(y)+mod:(x)-(y)
#define clr(a,b) memset(a,b,sizeof(a))
#define eps 1e-10
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> VI;
typedef pair<int, int> PII;

const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int mod = 1e9 + 7;
const int MX = (1 << 6) + 5;

int a[MX][MX];
double dp[10][MX], wr[10][MX];
inline int get_l(int x, int y) {return (x >> y) << y;}
inline int get_r(int x, int y) {return x + (1 << y);}
int l[10][MX], r[10][MX];
int main() {
#ifdef local
    freopen("in.txt", "r", stdin);
#endif // local
    int n; cin >> n;
    rep(i, 0, 1 << n) rep(j, 0, 1 << n) cin >> a[i][j];
    rep(i, 0, 1 << n) wr[n][i] = 1;
    rep(i, 0, 1 << n) r[n][i] = i;
    per(i, n, 0) rep(j, 0, 1 << n) {
        l[i][j] = get_l(j, n - i);
        r[i][j] = get_r(l[i][j], n - i - 1);
        if((j >> (n - i - 1)) % 2 == 0) {
            l[i][j] += (1 << (n - i - 1));
            r[i][j] += (1 << (n - i - 1));
        }
        rep(k, l[i][j], r[i][j]) if(a[j][k]) {
            wr[i][j] += wr[i + 1][j] * wr[i + 1][k] * a[j][k] / 100;
        }
    }
    double ans = 0;
    per(i, n, 0) rep(x, 0, 1 << n) if(wr[i + 1][x] > 0) {
        double tmp = 0;
        int L = l[i][x];
        int R = r[i][x];
        rep(y, L, R) tmp = max(tmp, dp[i + 1][y]);
        rep(y, L, R) {
            tmp += a[x][y] * wr[i + 1][x] * wr[i + 1][y] * (1 << (n - i - 1)) / 100;
        }
        dp[i][x] = dp[i + 1][x] + tmp;
    }
    rep(i, 0, 1 << n) ans = max(ans, dp[0][i]);
    printf("%.10f\n", ans);
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值