poj 3071 Football (概率 dp)
2015-01-29 17:00
375 查看
链接:poj 3071
题意:有2^n个队,相邻的两两打淘汰赛,n轮后必定会决出冠军,
求最后哪个队夺冠的概率最大
分析:dp[i][j]表示第i轮的时候,第j去支队伍赢的概率
则dp[i][j]的前提就是i-1轮的时候,j是赢的,且第i轮赢了对方
接下来就是找到第i轮的时候,他的可能队手(难点)
所有对手的编号为1-2^n,通过二进制可以发现规律,
若第j队和对手k队在第i轮比赛,那么(j-1)和(k-1)二进制第i位刚好相反,
从i+1位开始所有高位是一样的,可以利用位运算判断是否为对手
状态方程为:
dp[i][j]=sigma(dp[i-1][j]*dp[i-1][k]*p[j][k])
题意:有2^n个队,相邻的两两打淘汰赛,n轮后必定会决出冠军,
求最后哪个队夺冠的概率最大
分析:dp[i][j]表示第i轮的时候,第j去支队伍赢的概率
则dp[i][j]的前提就是i-1轮的时候,j是赢的,且第i轮赢了对方
接下来就是找到第i轮的时候,他的可能队手(难点)
所有对手的编号为1-2^n,通过二进制可以发现规律,
若第j队和对手k队在第i轮比赛,那么(j-1)和(k-1)二进制第i位刚好相反,
从i+1位开始所有高位是一样的,可以利用位运算判断是否为对手
状态方程为:
dp[i][j]=sigma(dp[i-1][j]*dp[i-1][k]*p[j][k])
#include<stdio.h> #include<string.h> int main() { double p[150][150],dp[150][150]; int n,i,j,k; while(scanf("%d",&n)!=EOF){ if(n==-1) break; int m=1<<n; for(i=1;i<=m;i++) for(j=1;j<=m;j++) scanf("%lf",&p[i][j]); memset(dp,0,sizeof(dp)); for(i=1;i<=m;i++) dp[0][i]=1.0; for(i=1;i<=n;i++) for(j=1;j<=m;j++) for(k=1;k<=m;k++) if(((j-1)>>(i-1)^1)==((k-1)>>(i-1))) //判断是否为对手 dp[i][j]+=dp[i-1][j]*dp[i-1][k]*p[j][k]; double max_p=0; int ans=0; for(i=1;i<=m;i++) if(dp [i]>max_p){ max_p=dp [i]; ans=i; } printf("%d\n",ans); } return 0; }
相关文章推荐
- POJ 3071 Football(概率DP)
- POJ 3071 Football 概率DP
- POJ-3071 Football (概率dp)
- POJ 3071 Football(简单 概率DP)
- POJ 3071 Football (概率DP)
- POJ3071-Football(概率DP+滚动数组)
- POJ 3071 Football (概率DP)
- POJ 3071 Football 概率DP 二进制优化
- poj-3071 Football 【概率dp,位运算】
- poj 3071 Football 概率dp
- POJ 3071 Football(概率DP)
- POJ 3071 Football 概率DP入门
- poj 3071 Football (概率DP水题)
- POJ 3071 Football(概率DP)
- poj 3071 Football 概率dp
- poj 3071 Football (概率DP)
- POJ 3071 Football(概率DP)
- POJ 3071 Football (动态规划-概率DP)
- poj 3071 football 概率dp
- POJ 3071 Football [概率DP]