暑期个人赛--第八场--D
2014-08-01 12:44
162 查看
452. 解码锦标赛
时间限制 1000 ms 内存限制 65536KB
题目描述
明光村迎来了一年一度的盛世——解码锦标赛,有 2^N 次个队伍从世界各村赶来参与比赛,编号为 1 - 2^N。赛制为每一轮晋级一半队伍,按序号大小两两比赛,淘汰弱者。一轮结束后,所有的胜者进入下一轮,依旧是按顺序两两比赛。比如第一轮就是 1 vs 2, 3 vs 4 ... 2^N - 1 vs 2^N。在一旁围观的 Mays 学姐告诉你,N次比赛后的胜者是唯一的。现在你拿到了一份各个参赛队伍的对抗胜率表 win,为2^N * 2^N 的矩阵, win[i][j] 为一位小数,代表i胜j的概率。
你能告诉 Mays 学姐最有可能获得世界冠军的是那支队伍吗?
输入格式
多组数据。每组第一行为 N ,N <= 8,接下来 N 行 N 列为对抗胜率矩阵。 保证 win[i][j] + win[j][i] = 1 (i != j)。 以 N=0 结束输入。
输出格式
对每组数据,输出胜率最大的队伍的序号。如果最大的两个概率相差不到 0.001,则认为胜率相等,输出序号最小者。
输入样例
2 0.0 0.1 0.2 0.3 0.9 0.0 0.4 0.5 0.8 0.6 0.0 0.6 0.7 0.5 0.4 0.0 2 0.0 0.8 0.1 0.4 0.2 0.0 0.2 0.6 0.9 0.8 0.0 0.3 0.6 0.4 0.7 0.0 0
输出样例
2 4
赛中提交:NULL
赛后AC:Y
题目大意:
有2的n次方个人伍参加比赛,采用两两淘汰晋级制(七龙珠的武道大会),求最后胜率最大的人。
思路:
也就是说要决出最终胜者,一个人一共要打n场比赛。
很明显这是一个dfs的题目,在一个完美二叉树上做递归运算,再加上记忆化搜索优化时间
递推式:
dp[i][j]表示第i号选手在第j次比赛中获胜的概率。
p[i][j]表示第i号选手击败第j号选手的概率
dp[i][j]=dp[i][j-1]*segma(dp[k][j-1]*p[i][k]) (k为i在第n次比赛中的兄弟树的所有最末尾的孙子序号)
下面是AC代码:
#include <iostream> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string> #include <vector> #include <list> #include <map> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <numeric> #include <functional> #define maxn 500 using namespace std; double dp[maxn][10],p[maxn][maxn]; int n; const double eps=0.001; double dfs(int num,int level) { if(dp[num][level]!=-1){ //printf("(%d %d):%lf \n",num,level,dp[num][level]); return dp[num][level]; } else{ double sum=0; int tmp1=pow(2,level-1); if(((num-1)/tmp1)%2==0){ for(int i=((num-1)/tmp1+1)*tmp1;i<((num-1)/tmp1+2)*tmp1;i+=1){ sum+=dfs(i+1,level-1)*p[num][i+1]; } } else{ for(int i=((num-1)/tmp1-1)*tmp1;i<((num-1)/tmp1)*tmp1;i+=1){ sum+=dfs(i+1,level-1)*p[num][i+1]; } } //printf("aaaa%lf\n",sum); return dp[num][level]=dfs(num,level-1)*sum; } } int main() { while(1){ scanf("%d",&n); if(!n){ break; } int N=pow(2,n); for(int i=1;i<=N;i+=1){ for(int j=1;j<=n;j+=1){ dp[i][j]=-1.0; } } for(int i=1;i<=N;i+=1){ for(int j=1;j<=N;j+=1){ scanf("%lf",&p[i][j]); if((i%2==0&&j==i-1)||(j%2==0&&i==j-1)){ dp[i][1]=p[i][j]; } } } double maxp=0,tmp; int ans=0; for(int i=1;i<=N;i+=1){ tmp=dfs(i,n); //printf("--%d %lf\n",i,tmp); if(tmp>maxp+eps){ maxp=tmp; ans=i; } } printf("%d\n",ans); } return 0; }
相关文章推荐
- 暑期个人赛--第八场--A
- 暑期个人赛--第八场--C(自己坑自己~!!!!)
- 暑期个人赛--第八场--B(关于手写队列的启示+题目有坑)
- (待切,标记上)暑期个人赛--第八场--E
- 暑期个人赛--第一场--C
- 2014/07/26 暑期个人赛一(每周)
- 暑期个人赛--第六场--B(常复习~!!!)
- (待切,标记上)暑期个人赛--第七场--E
- 中石油 暑期集训个人赛第一场 题解
- 【个人感悟】暑期总结与感想
- 暑期个人赛--第一场--D
- 暑期个人赛--第六场--A
- 暑期个人赛--第六场--E
- 暑期个人赛--第七场--B
- 暑期个人赛--第七场--C
- 暑期个人赛--第三场--A
- 暑期培训计划之个人计划
- 2014暑期最后一次个人赛
- 2017暑期ACM俱乐部个人训练赛第3场
- 2017暑期ACM俱乐部个人训练赛第2场