poj 3071 Football <DP>
链接:http://poj.org/problem?id=3071
题意: 有 2^n 支足球队,编号 1~2^n,现在给出每支球队打败其他球队的概率,问哪只球队取得冠军的概率最大?
思路:
设dp[i][j] 为第 i 轮, 第 j 支球队胜的概率~
那么dp[i][j]=dp[i-1][j] * ∑dp[i-1][k]*p[j][k] , k 为相应轮 j 可能面对的对手~
那么在第 i 轮, 第 j 队的对手怎样尽快求得呢, (j从0开始)~
对于第一轮,其可能的对手只有一个 为 j^1, 第 i 轮时其可能的对手有 2^(i-1)个,
而其第一个的位置为 (j^1)>>(i-1)<<(i-1) 共 2^(i-1) 个~
1 #include <stdio.h> 2 double p[128][128]; 3 double dp[8][128]; 4 int main() 5 { 6 int n,i,j,k,start,num; 7 8 while(scanf("%d",&n),n!=-1){ 9 int size=1<<n, ans=0; 10 for(i=0;i<size;i++) 11 for(j=0;j<size;j++){ 12 scanf("%lf",&p[i][j]); 13 } 14 for(i=0;i<size;i++){ 15 dp[0][i]=1.0; 16 } 17 for(k=1;k<=n;k++){ 18 for(i=0;i<size;i++){ 19 dp[k][i]=0.0; 20 num=1<<(k-1); 21 start=(((i>>(k-1))^1)<<(k-1)); 22 for(j=start;j<num+start;j++){ 23 dp[k][i]+=dp[k-1][j]*p[i][j]; 24 } 25 dp[k][i]*=dp[k-1][i]; 26 if(k==n){ 27 if(dp[n][i]>dp[n][ans]){ 28 ans=i; 29 } 30 } 31 } 32 } 33 34 printf("%d\n",ans+1); 35 } 36 return 0; 37 }