题目:Football
思路:
就是用一个类似于线段树的树形结构维护下。
大概我是唯一一个不会推公式来写这么诡异的结构的,肯定是数据结构学傻了。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
#define db double
#define maxn 7
#define maxm (1<<maxn)
struct Node{
int l,r;
};
int n,m;
double p[maxm+5][maxm+5];
Node a[maxm*4+5];
double f[maxm+5][maxn+5];
void readin() {
m=(1<<n);
for(int i=1;i<=m;i++) {
for(int j=1;j<=m;j++) {
scanf("%lf",&p[i][j]);
}
}
}
void make_tree(int o,int l,int r,int d) {
if(l==r) {
a[o].l=l,a[o].r=r;
f[l][d]=1;
return ;
}
int mid=l+(r-l)/2;
int lch=o*2,rch=o*2+1;
make_tree(lch,l,mid,d+1),make_tree(rch,mid+1,r,d+1);
a[o].l=a[lch].l,a[o].r=a[rch].r;
for(int i=a[lch].l;i<=a[lch].r;i++) {
for(int j=a[rch].l;j<=a[rch].r;j++) {
f[i][d]+=f[i][d+1]*f[j][d+1]*p[i][j];
f[j][d]+=f[j][d+1]*f[i][d+1]*p[j][i];
}
}
}
void init() {
memset(f,0,sizeof(f));
}
void print() {
int ans=-1;
double s=-1;
for(int i=1;i<=m;i++) {
if(f[i][1]>s) {
s=f[i][1];
ans=i;
}
}
printf("%d\n",ans);
}
int main() {
while(~scanf("%d",&n)&&~n) {
readin();
init();
make_tree(1,1,m,1);
print();
}
return 0;
}