zoj2893 Evolution(矩阵快速幂)

题意:就是说物种进化,有N种物种,编号是0——N-1,M次进化后,问你编号为N-1的物种有多少数量;其中要注意的就是i物种进化到j物种的概率是p;(那么剩下的不要忘了);所以单位矩阵初始化对角线的值为1,

然后根据题目进化的概率进行加减;

比如P(i, j) = 0.3,则:

mat[i][j] += 0.3

mat[i][i] -= 0.3;

把题目转化为数学模型,分析后就是有一个初始序列,有一个进化率矩阵,求的是初始序列与进化率矩阵进行m次运算后,初始序列最后一位的答案。那么显然,可以对进化率矩阵进行快速幂计算。

 1 #include<iostream>
 2 #include<cstring>
 3 #define maxn 205
 4 using namespace std;
 5 struct mat{
 6     double a[maxn][maxn];
 7 };
 8 mat res;
 9 int n,m;
10 long long A[maxn];
11 mat mat_mul(mat x,mat y){
12     mat ans;
13     memset(ans.a,0,sizeof(ans.a));
14     for (int i=0;i<n;i++)
15         for (int j=0;j<n;j++)
16         for (int k=0;k<n;k++)
17             ans.a[i][j]+=x.a[i][k]*y.a[k][j];
18     return ans;
19 }
20 mat mat_pow(mat res,int k){
21     mat c=res;
22     k--;
23     while (k){
24         if (k&1) res=mat_mul(res,c);
25         k>>=1;
26         c=mat_mul(c,c);
27     }
28     return res;
29 }
30 int main(){
31     int x,y;
32     int t;
33     double q;
34     while (cin >> n >> m && n+m!=0){
35         for (int i=0;i<n;i++) cin >> A[i];
36         memset(res.a,0,sizeof(res.a));
37         for (int i=0;i<n;i++) res.a[i][i]=1;
38         cin >> t;
39         while (t--){
40             cin >> x >> y >> q;
41             res.a[x][y]+=q;
42             res.a[x][x]-=q;
43         } 
44         res=mat_pow(res,m);
45         double ans=0;
46         for (int i=0;i<n;i++){
47             ans+=A[i]*res.a[i][n-1];
48         }
49         cout << (long long)(ans+0.5) << endl;
50     }
51     return 0;
52 }

 

posted @ 2018-02-11 18:26  Changer-qyz  阅读(158)  评论(0编辑  收藏  举报