xcoj 1208 矩阵

赛场上一开始以为是递推,交了一发希望以为能卡着线过(毕竟是O(5N)的),结果WA了。

  又以为是dp,最后半小时尝试各种YY。。。各种WA

实际上取每次transfer中最大的概率然后递推是不对的。。。因为最终结果是每次的总乘积

sol:以第二个样例为例:

因为A[j][i]表示j->i的概率,所以把A先反转一下,令A[i][j]表示i->j的概率。

设初始矩阵B[0 0 1 0 0],B[1][i]表示当前角色i的概率

乘一次A,就得到新矩阵[0.2 0.1 0.0 0.4 0.3]

B是1x5的矩阵,A是5x5的矩阵,B[1][j]=sigma(k=1 to 5)【B[1][k]*A[k][j]】就是所有下一关玩到角色j的概率。

这样,令B=B*A^(n-1)。之后B[1][i]就表示n次后第i个角色的概率。找最大就行了。

注意精度1e-6

 1 #include<iostream>
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 #define eps 1e-6
 8 typedef unsigned long int ULL;
 9 typedef vector<double> vec;
10 typedef vector<vec> mat;
11 //const ULL P=9973;
12 int T,n,st;
13 double db[10][10];
14 
15 mat mul(mat &A,mat &B)      //return A*B
16 {
17     mat C(A.size(),vec(B[0].size()));
18     for (int i=0; i<(int)A.size(); i++)
19     {
20         for (int k=0; k<(int)B.size(); k++)
21         {
22             for (int j=0; j<(int)B[0].size(); j++)
23             {
24                 C[i][j]=(C[i][j]+A[i][k]*B[k][j]);
25             }
26         }
27     }
28     return C;
29 }
30 
31 mat m_pow(mat A,int m)      //return A^m
32 {
33     mat B(A.size(),vec(A.size()));
34     for (int i=0; i<(int)A.size(); i++)
35         B[i][i]=1;
36     while (m>0)
37     {
38         if (m&1)    B=mul(B,A);
39         A=mul(A,A);
40         m>>=1;
41     }
42     return B;
43 }
44 
45 int main()
46 {
47     //freopen("out.txt","w",stdout);
48     cin>>T;
49     while(T--)
50     {
51         cin>>n;
52         mat A(5,vec(5));
53         mat B(1,vec(5));
54         for (int i=0; i<5; i++)
55         {
56             B[0][i]=0;
57             for (int j=0; j<5; j++)
58                 cin>>A[j][i];
59         }
60 /*
61         for(int i=0;i<5;i++)
62         {
63             for(int j=0;j<5;j++)
64                 cout<<A[i][j]<<" ";
65             cout<<endl;
66         }
67 */
68         A=m_pow(A,n-1);
69         cin>>st;
70 
71         B[0][st-1]=1;
72         B=mul(B,A);
73 
74         for(int i=0;i<5;i++)
75             cout<<B[0][i]<<" ";
76         cout<<endl;
77 
78         double  mx=B[0][0];
79         int     mxi=0;
80         for(int i=1;i<5;i++)
81         {
82             if((fabs(B[0][i]-mx)>eps)&&(B[0][i]>mx))
83             {
84                 mx=B[0][i];
85                 mxi=i;
86             }
87         }
88         cout<<mxi+1<<endl;
89     }
90     return 0;
91 }
View Code
原文地址:https://www.cnblogs.com/pdev/p/4533100.html