poj3071football【概率DP】
2015-10-14 21:36
232 查看
这个题已经搁浅太久
dp[i][j]表示第i轮的时候,第j去支队伍赢的概率。
那么dp[i][j]的前提就是i-1轮的时候,j是赢的,而且第i轮赢了对方
接下来就是找到第i轮的时候,他的可能队手
通过二进制可以发现规律,所有高位是一样的,第i位刚好相反,所以用位运算可以巧妙解决,见代码
dp[i][j]=sigma(dp[i-1][j]*dp[i-1][k]*p[j][k])
dp[i][j]表示第i轮的时候,第j去支队伍赢的概率。
那么dp[i][j]的前提就是i-1轮的时候,j是赢的,而且第i轮赢了对方
接下来就是找到第i轮的时候,他的可能队手
通过二进制可以发现规律,所有高位是一样的,第i位刚好相反,所以用位运算可以巧妙解决,见代码
dp[i][j]=sigma(dp[i-1][j]*dp[i-1][k]*p[j][k])
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define eps 1e-10 #define N (1<<7)+5 #define inf 1<<20 #define zero(a) (fabs(a)<eps) #define lson (step<<1) #define rson (step<<1|1) using namespace std; double p ; double dp[10] ; 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",&p[i][j]); memset(dp,0,sizeof(dp)); for(int i=0;i<(1<<n);i++) dp[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))) dp[i][j]+=dp[i-1][k]*dp[i-1][j]*p[j][k]; } } } double ans=0; int idx=-1; for(int i=0;i<(1<<n);i++) if(dp [i]>ans){ ans=dp [i]; idx=i+1; } printf("%d\n",idx); } return 0; }
相关文章推荐
- PHP操作MySQL服务器
- C++:操作符
- Ubuntu15.04中测试安装的opencv2.4.9 时遇到usr/bin/ld: cannot find -lcufft解决方法。
- mysql创建触发器
- 创建类
- git命令自动补全
- 软件测试管理
- LINUX下图形界面切换到文本模式 以及~和/的区别
- linux中memset的正确用法
- latex 插入代码、代码框、代码配色
- JavaWeb三大组件——过滤器的运行机制理解
- londiste3 copy table' snapshot & PostgreSQL logical replication's snapshot 不同之处
- eclipse中导入项目后中文成乱码解决办法
- github如何删除一个repository(仓库)
- 经典测温电路
- 绘制模式之硬加速和软加速
- 跑Action Bank代码流程
- Foundation kit介绍
- python requests遭遇死锁小记
- Vi and Vim Macro Tutorial: How To Record and Play