• bzoj 1297 矩阵乘法变形


    首先对于矩阵乘法的功能有很多,记得有篇论文叫矩阵乘法在信息学竞赛中的应用,里面详细介绍了矩阵的

    作用

    其中一个就是求图的固定时间方案数,也就是给定一张图,每两个点之间由一条边长为1的边相连,

    求任意两点之间的路径和为x的方案数

    论文很详细,这里只做简要的说明

    对于矩阵乘法,具体代码为

    for i:=1 to n do 
        for j:=1 to n do     
            for k:=1 to n do a[i,j]:=a[i,j]+b[i,k]*c[k,j];

    那么如果b矩阵,b[i,j]代表I到J,路径长为x的方案数,c[i,j]代表I到J,路径长为Y的方案数,那么k相当于中转点

    c[i,j]这样转移之后,根据加法原理,就代表I到J,路径长为X+Y的方案数,这样就可以转移了

    那么我们初始矩阵,ans[I,J]=1代表I,J之间有边(这里指有向边),将这个矩阵自乘X次得到的就是答案矩阵了,

    即ans[I,J]为I到J长为X的方案数

    那么对于这道题,他的路径长度可以为1-9,那么我们把一个点拆成一条有向链,然后假设连接I,J长度为3,

    就连I链中第3个点,J中第一个点,长度为1的边就行了

    /**************************************************************
        Problem: 1297
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:3128 ms
        Memory:348 kb
    ****************************************************************/
     
    //By BLADEVIL
    type
        rec                     =array[0..100,0..100] of longint;
         
    var
        n, t                    :longint;
        sum, ans                :rec;
     
    procedure init;
    var
        i, j                    :longint;
        len                     :longint;
        ss                      :char;
    begin
        readln(n,t);
        for i:=1 to n do
        begin
            for j:=1 to n do
            begin
                read(ss);
                len:=ord(ss)-48;
                if len=0 then continue;
                sum[(i-1)*9+len,(j-1)*9+1]:=1;
            end;
            readln;
        end;
        for i:=1 to n do
            for j:=0 to 7 do sum[(i-1)*9+1+j,(i-1)*9+j+2]:=1;
     
    end;
     
    function mul(a,b:rec):rec;
    var
        i, j, k                 :longint;
    begin
        fillchar(mul,sizeof(mul),0);
        for i:=1 to n*9 do
            for j:=1 to n*9 do
                for k:=1 to n*9 do mul[i,j]:=(mul[i,j]+a[i,k]*b[k,j]) mod 2009;
    end;
     
    procedure main;
    var
        p                       :longint;
        i, j                    :longint;
    begin
        for i:=1 to n*9 do ans[i,i]:=1;
        p:=t;
        while p<>0 do
        begin
            if p mod 2=1 then ans:=mul(sum,ans);
            sum:=mul(sum,sum);
            p:=p div 2;
        end;
        writeln(ans[1,(n-1)*9+1]);
    end;
     
    begin
        init;
        main;
    end.
  • 相关阅读:
    好记性不如烂笔头-linux学习笔记2kickstart自动化安装和cacti
    好记性不如烂笔头-linux学习笔记1
    关于TP5中的依赖注入和容器和facade
    vbs 脚本2
    vbs脚本
    Memcache 和 Radis 比较
    MongoDB 索引的使用, 管理 和优化
    mysql大数据高并发处理
    sql处理高并发
    LB 负载均衡的层次结构
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3472253.html
Copyright © 2020-2023  润新知