• ZOJ 2853 Evolution 【简单矩阵快速幂】


    这道题目第二次看的时候才彻底理解了是什么意思

    把题目转化为数学模型分析后就是 有一个初始序列, 有一个进化率矩阵

    求的是初始序列 与进化率矩阵进行 m 次运算后, 初始序列最后一位的答案

    那么显然,可以对进化率矩阵进行快速幂计算

    Example

    Let's assume that P(0, 1) = P(1, 2) = 1, and at the beginning of a sub-process, the populations of 0, 1, 2 are 40, 20 and 10 respectively, then at the end of the sub-process, the populations are 0, 40 and 30 respectively.

    这个栗子看懂了这题就会懂了。

     Source Code:

    //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
    #include <stdio.h>
    #include <iostream>
    #include <fstream>
    #include <cstring>
    #include <cmath>
    #include <stack>
    #include <string>
    #include <map>
    #include <set>
    #include <list>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #define Max(a,b) (((a) > (b)) ? (a) : (b))
    #define Min(a,b) (((a) < (b)) ? (a) : (b))
    #define Abs(x) (((x) > 0) ? (x) : (-(x)))
    #define MOD 1000000007
    #define pi acos(-1.0)
    
    using namespace std;
    
    typedef long long           ll      ;
    typedef unsigned long long  ull     ;
    typedef unsigned int        uint    ;
    typedef unsigned char       uchar   ;
    
    template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
    template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}
    
    const double eps = 1e-7      ;
    const int N = 210            ;
    const int M = 1100011*2      ;
    const ll P = 10000000097ll   ;
    
    int n, m;
    
    struct Mat{
        double mat[N][N];
    };
    
    Mat operator * (Mat a, Mat b){
        Mat c;
        memset(c.mat, 0, sizeof(c.mat));
        for(int k = 0; k < n; ++k){
            for(int i = 0; i < n; ++i){
                if(a.mat[i][k] <= 0)    continue;   //
                for(int j = 0; j < n; ++j){
                    if(b.mat[k][j] <= 0)    continue;   //
                    c.mat[i][j] += a.mat[i][k] * b.mat[k][j];
                }
            }
        }
        return c;
    }
    
    Mat operator ^ (Mat a, int k){
        Mat c;
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < n; ++j){
                c.mat[i][j] = (i == j); //init
            }
        }
        for(; k; k >>= 1){
            if(k & 1)   c = c * a;  //key
            a = a * a;
        }
        return c;
    }
    
    int main(){
        int i, j, t, k, u, v, numCase = 0;
        while(EOF != scanf("%d%d",&n,&m)){
            if(0 == n && 0 == m)    break;
            double val;
            Mat a, b;
            memset(a.mat, 0, sizeof(a.mat));
            memset(b.mat, 0, sizeof(b.mat));
            for(i = 0; i < n; ++i)  b.mat[i][i] = 1;
            for(i = 0; i < n; ++i)  scanf("%lf", &a.mat[i][i]);
            scanf("%d",&t);
            while(t--){
                scanf("%d%d%lf",&u,&v,&val);
                b.mat[u][u] -= val; //
                b.mat[u][v] = val;  //
            }
            b = b ^ m;
            double cur = 0;
            for(i = 0; i < n; ++i){
                cur += b.mat[i][n - 1] * a.mat[i][i];
            }
            /*
            for(i = 0; i < n; ++i){
                for(j = 0; j < n; ++j){
                    cout << c.mat[i][j] << ' ';
                }
                cout << endl;
            }
            */
            printf("%.0lf
    ",cur);
        }
        return 0;
    }
    
    /*
    3 1
    40 20 10
    2
    0 1 1.0
    1 2 1.0
    */
  • 相关阅读:
    无障碍开发(十五)之好心办坏事
    无障碍开发(十四)之Android /iOS平台无障碍功能
    无障碍开发(十三)之盲人是如何使用手机的之屏幕阅读器Screen Reader
    无障碍开发(十二)之怎样做好信息无障碍?
    LABjs学习(一)之无阻塞动态并行加载脚本文件以及管理执行顺序
    jQuery选择器引入
    面向对象-标准的手机类代码及其测试
    面向对象-this关键字的内存图解
    面向对象-this关键字的概述和应用
    第一个jQuery程序
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/4312789.html
Copyright © 2020-2023  润新知