您的位置:首页 > 其它

POJ 3071 FootBall 概率dp

2017-01-10 16:31 330 查看

题目分析

这道题其实就是全概率公式的应用,可以定义状态为ans[i][j],其表示第j个队在第i轮胜出的概率,这样的话状态转移方程就很好写了。

ans[i][j]=∑ans[i−1][j]∗ans[i−1][k]∗a[j][k];

比如8个队,用2进制表示为 000, 001,010,011,100,101,110,111。于是我们会发现每一轮只需要将队伍数表示的2进制右移i-1为,并且移动完成后异或1相等的就是这一轮这个队需要面对赢得队伍,可以发现二进制还是很神奇。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1<<10;

double a[maxn][maxn], ans[10][maxn];

int main(){
int n;
while(scanf("%d", &n) != EOF && n != -1){
for(int i = 0; i < (1<<n); i++)
for(int j = 0; j < (1<<n); j++)
scanf("%lf", &a[i][j]);
memset(ans, 0, sizeof(ans));
for(int i = 0; i < (1<<n); i++) ans[0][i] = 1;

for(int i = 1; i <= n; i++)
for(int j = 0; j < (1<<n); j++)
for(int k = 0; k < (1<<n); k++)
if(((j>>(i-1))^1) == (k>>(i-1))) ans[i][j] += ans[i-1][j]*a[j][k]*ans[i-1][k];
double ret = 0;
int id = 1;
for(int i = 0; i < (1<<n); i++)
if(ans
[i] > ret){
ret = ans
[i];
id = i+1;
}
printf("%d\n", id);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: