您的位置:首页 > 其它

poj 3071 概论 dp

2012-09-19 17:19 176 查看
/*
题目:http://poj.org/problem?id=3071
题意:
有(1<<N)个人进行N次比赛,每次比赛都是第i个人和第i+1个人进行,赢的人能进入下一轮,
输的人就不能继续比赛,N轮比赛之后,只会有一个人留下来,问谁最终留下来的概率最大。
dp[i][j],表示第i轮,第j个人获胜的概论;
分析的状态转移方程为:
dp[i][j]=sum{dp[i-1][j]*dp[i-1][k]*p[j][k]} (1<<n)>=k>(1<<(i-1));
边界条件 dp[0][j]=1;
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<memory.h>
using namespace std;
const int maxn=1<<7;
double  dp[10][maxn+2],p[maxn+2][maxn+2];
int n;
int main()
{
while(scanf("%d",&n),n!=-1)
{
int i,j,k;
int m=1<<n;
for(i=0; i<=m; i++) dp[0][i]=1.0;
for(i=1; i<=m; i++)
{
for(j=1; j<=m; j++)
{
scanf("%lf",&p[i][j]);
}
}
for(i=1; i<=n; i++)
{
int key=1<<(i-1);
for(j=1; j<=m; j++)
{
dp[i][j]=0.0;
int s , e;
s = 0  ;
int cnt = 0 ;
while(s+key<j)   s+=key ,cnt++ ;
if((cnt&1)==0)
{
s += key;
e = s +key ;
s = s + 1 ;
}
else
{
e = s ;
s = s - key  + 1 ;
}
for(k=s; k<=e&&k<=m; k++)
{
dp[i][j]+=dp[i-1][j]*dp[i-1][k]*p[j][k];
}
}
}
double ans=-1.0;
int res=0;
for(i=1; i<=m; i++)
{
if(ans<dp
[i]) ans=dp
[i],res=i;
}
printf("%d\n",res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: