GYM101147-K. Touristic Trip-概率DP+条件概率

理解了Q巨的代码。模写了一发。

 dp数组含义为在第j个城市发明信片序列第i张的概率。

按照发放顺序转移

对于条件概率的分子,我么可以知道在这个dp数组里面只能从dp[Q][Z]转移过去。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 double dp[30][30];
 6 double path[30][30];
 7 double send[30][30];
 8 int n[30];
 9 int main()
10 {
11     int T;
12     freopen("trip.in","r",stdin);
13     cin >>T;
14     while(T--){
15         int N,M,K,Q,Z;
16         cin >> N >> M >> K >> Q >> Z;
17         Q++;
18         Z++;
19         for (int i = 1; i<=N; i++){
20             for (int j = 1;  j<=N; j++)
21                 cin >> path[i][j];
22         }
23         for (int i = 1; i<=N; i++){
24             for (int j = 1; j<=M ; j++)
25                 cin >> send[i][j];
26         }
27         for (int i = 1; i<=K; i++){cin >> n[i];n[i]++;}
28         memset(dp,0,sizeof(dp));
29         dp[1][1] = send[1][n[1]];
30         for (int m = 2; m<=K; m++)
31             for (int now = 1; now<=N; now++ ){
32                 for (int f = 1; f <=N; f++)
33                     dp[m][now] += dp[m-1][f]*path[f][now];
34             dp[m][now]*=send[now][n[m]];
35             }
36         double f1 = 0;
37         for (int i = 1; i<=N; i++)
38             f1+=dp[K][i];
39         memset(dp,0,sizeof(dp));
40         if (Q!=1||1==Z)dp[1][1] = send[1][n[1]];
41         for (int m = 2; m<=K; m++)
42             for (int now = 1; now<=N; now++ ){
43                 for (int f = 1; f <=N; f++)
44                     dp[m][now] += dp[m-1][f]*path[f][now];
45             dp[m][now]*=send[now][n[m]];
46             if (m==Q&&now!=Z) dp[m][now] = 0;
47             }
48         double f2 = 0;
49         for (int i = 1; i<=N; i++)
50             f2+=dp[K][i];
51         printf("%.3f\n",f2/f1);
52     }
53     return 0;
54 }

 

posted @ 2017-04-16 21:15  HITLJR  阅读(341)  评论(0编辑  收藏  举报