zoukankan      html  css  js  c++  java
  • 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
    */
  • 相关阅读:
    页面上有10个多选框,实现三个按钮(重置、反选、全选)功能
    鼠标点哪 哪出15*15的圆型div
    es写简单的留言板
    面试准备(3)事件循环
    面试准备(2)async+await的使用与原理
    面试准备(1)重排与重绘和验证码
    vue项目修改el-input样式
    echarts画雷达图详解
    决心
    国庆中秋
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/4312789.html
Copyright © 2011-2022 走看看