【概率dp】POJ 3071
2012-02-04 02:10
281 查看
http://poj.org/problem?id=3071
题意是又2^n支球队,球队两两之间进行比赛,例如开始时0-1, 2-3, 4-5, 6-7...............然后晋级后又是相邻两两之间比赛,问最大可能的胜者编号。
方法:概率dp。
设dp[i][j]表示第i轮j队胜的概率, 其中dp[i][j] += ∑dp[i-1][k]*p[j][k],下面的hint已经给出了提示,接着我认为比较棘手的是如何找出该轮应该进行比赛的两支球队,开始写错了,看了别人,发现一个神位运算((k>>(i-1))^1) == j>>(i-1) ,后来想了一下,自己也明白什么回事了,可以把晋图级画成一棵二叉树,树叶的编号是一开始的编号,那么(k>>(i-1))^1 j>>(i-1)表示父结点的两个儿子结点,额,可能讲得不清楚,可以画图看看。
题意是又2^n支球队,球队两两之间进行比赛,例如开始时0-1, 2-3, 4-5, 6-7...............然后晋级后又是相邻两两之间比赛,问最大可能的胜者编号。
方法:概率dp。
设dp[i][j]表示第i轮j队胜的概率, 其中dp[i][j] += ∑dp[i-1][k]*p[j][k],下面的hint已经给出了提示,接着我认为比较棘手的是如何找出该轮应该进行比赛的两支球队,开始写错了,看了别人,发现一个神位运算((k>>(i-1))^1) == j>>(i-1) ,后来想了一下,自己也明白什么回事了,可以把晋图级画成一棵二叉树,树叶的编号是一开始的编号,那么(k>>(i-1))^1 j>>(i-1)表示父结点的两个儿子结点,额,可能讲得不清楚,可以画图看看。
#define N (1<<7)+10 double p ; double dp ;//第i轮j队胜的概率dp[i][j] += ∑dp[i-1][k]*p[j][k] int main(){FRE; int n; while(scanf("%d",&n) && n!=-1){ int i,j; int m = (1<<n); for(i=0;i<m;i++){ for(j=0;j<m;j++){ scanf("%lf",&p[i][j]); } dp[0][i] = 1; } int k; for(i=1;i<=n;i++){ for(j=0;j<m;j++){ double tmp = 0.0; dp[i][j] = dp[i-1][j]; for(k=0;k<m;k++){ if(((k>>(i-1))^1) == j>>(i-1)){ tmp += dp[i-1][k]*p[j][k]; } } dp[i][j] *= tmp; } } int ans=0; for(i=0;i<m;i++){ if(dp [i] > dp [ans])ans=i; } printf("%d\n",ans+1); } return 0; }
相关文章推荐
- POJ 3071 Football (概率DP)
- POJ-3071 Football 概率DP
- POJ3071-Football(概率DP+滚动数组)
- Football - POJ 3071 概率dp
- 【POJ 3071 Football】+ 概率DP
- poj - 3071 Football (概率dp)
- POJ 3071 Football (很好的一个概率DP)
- poj 3071 概率dp
- POJ-3071 Football (概率dp)
- POJ 3071 概率DP
- poj 3071 概率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)
- (简单) 树形dp+概率 POJ 3071 Football
- POJ 3071 Football(概率DP)