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 }
posted on 2015-05-27 12:14 Pentium.Labs 阅读(830) 评论(0) 编辑 收藏 举报