1023: Pong’s Birds(機率)

1023: Pong’s Birds

時間限制: 1 Sec  內存限制: 128 MB
提交: 94  解決: 21
[提交][狀態][討論版]

題目描述

In order to train his birds, Pong is holding a competition for them. (He have birds, does he?) He have 2n birds,
so he want to hold elimination series. Literally, if n = 2 and he has 4 birds identified as 1,2,3,4, he would first hold competition for 1 and 2, 3 and 4, the one fails would be eliminated and then he holds competition for the winners. 
According to his long observation, for each pair of birds he knows the probability to win for each bird, and he want to know the probability of each bird to be the final winner.

輸入

For the first row there is an integer T(T ≤ 100), which is the number of test cases.
For each case , first row is an integer n(1 ≤ n ≤ 7), for the next 2n rows , each row has 2n real numbers as the probability to win for the i-th when competed to j-th bird. It is promised that for each i, j p[i][j] + p[j][i] = 1 and p[i][i] = 0;

輸出

For each case you should output a line with 2n real numbers, which is the probability of i-th bird be the final winner. Rounded to 3 decimal places.
Make sure to output a space character after each number, to prevent the Presentation Error.

樣例輸入

1
1
0 0.5
0.5 0

樣例輸出

0.500 0.500

提示

 

 

求隊伍奪冠機率,畫圖找下規律遞推,php

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int MAXN = (1 << 7) + 5;
 5 double p[MAXN][MAXN];
 6 double dp[8][MAXN];//dp[i][j]表示第i輪j隊伍出線機率
 7 
 8 int main()
 9 {
10     int t;
11     int n;
12     int n2;
13     int i, j, k;
14     int grp;
15     for (j = 0; j < MAXN; ++j) {
16         dp[0][j] = 1;
17     }
18     scanf("%d", &t);
19     while (t--) {
20         scanf("%d", &n);
21         n2 = 1 << n;
22         for (i = 0; i < n2; ++i) {
23             for (j = 0; j < n2; ++j) {
24                 scanf("%lf", &p[i][j]);
25             }
26         }
27 
28         for (i = 1; i <= n; ++i) {
29             for (j = 0; j < n2; ++j) {
30                 grp = j / (1 << (i - 1));//
31                 grp ^= 1;//奇偶互換
32                 dp[i][j] = 0;
33                 for (k = grp << (i - 1); k < ((grp + 1) << (i - 1)); ++k) {
34                     dp[i][j] += dp[i - 1][j] * dp[i - 1][k] * p[j][k];
35                 }
36             }
37         }
38 
39         for (i = 0; i < n2 - 1; ++i) {
40             printf("%.3lf ", dp[n][i]);
41         }
42         printf("%.3lf\n", dp[n][n2 - 1]);
43     }
44     return 0;
45 }

 

 

記憶化搜索c++

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int MAXN = (1 << 7) + 5;
 5 double p[MAXN][MAXN];
 6 double dp[8][MAXN];//dp[i][j]表示第i輪j隊伍出線機率
 7 
 8 double dfs(int i, int j)
 9 {
10     if (i == 0) {
11         return 1;
12     }
13     if (dp[i][j] >= 0) {
14         //printf("%lf\n", dp[i][j]);
15         return dp[i][j];
16     }
17     int k;
18     int grp;
19     grp = j / (1 << (i - 1));//
20     grp ^= 1;//奇偶互換
21     dp[i][j] = 0;
22     for (k = grp << (i - 1); k < ((grp + 1) << (i - 1)); ++k) {
23         dp[i][j] += dfs(i - 1, j) * dfs(i - 1, k) * p[j][k];
24     }
25     return dp[i][j];
26 }
27 
28 int main()
29 {
30     int t;
31     int n;
32     int n2;
33     int i, j, k;
34     int grp;
35     scanf("%d", &t);
36     while (t--) {
37         scanf("%d", &n);
38         n2 = 1 << n;
39         for (i = 0; i < n2; ++i) {
40             for (j = 0; j < n2; ++j) {
41                 scanf("%lf", &p[i][j]);
42             }
43         }
44         
45         //memset(dp, -1, sizeof(dp));//不能使用
46         for (i = 1; i <= n; ++i) {
47             for (j = 0; j < n2; ++j) {
48                 dp[i][j] = -1;
49             }
50         }
51 
52         for (i = 0; i < n2 - 1; ++i) {
53             printf("%.3lf ", dfs(n, i));
54         }
55         printf("%.3lf\n", dfs(n, n2 - 1));
56     }
57     return 0;
58 }
View Code
相關文章
相關標籤/搜索