zoukankan      html  css  js  c++  java
  • BZOJ 1898: [Zjoi2004]Swamp 沼泽鳄鱼(矩阵乘法)

    可以发现,如果没有鳄鱼,那么就是裸地一道题,但是可以发现鳄鱼最多每12次重复,那么就少于12的那部分dp,其他的就矩阵乘法就行了

    PS:第一次吧矩阵乘法AC了好开心QAQ

    CODE:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define mod 10000
    #define maxn 60
    using namespace std;
    struct mat{
        int n,m,a[maxn][maxn];
        mat(){n=m=0;memset(a,0,sizeof(a));}
        int I(int _x){n=m=_x;for (int i=1;i<=n;i++) a[i][i]=1;}
    };
    mat operator *(const mat &x,const mat &y){
        mat ans;
        ans.n=x.n;
        ans.m=y.m;
        for (int i=1;i<=ans.n;i++)
        for (int j=1;j<=ans.m;j++)
            for (int k=1;k<=x.m;k++){
            ans.a[i][j]+=x.a[i][k]*y.a[k][j];
            ans.a[i][j]%=mod;
            }
        return ans;
    }
    mat power(mat x,int y){
        mat ans;ans.I(x.n);
        for (;y;y>>=1){
        if (y&1) ans=ans*x;
        x=x*x;
        }
        return ans;
    }
    int n,m,s,e,fn,ti;
    bool b[60][60];
    int a[20][7],t[60],f[60][60][15];
    int main(){
        scanf("%d%d%d%d%d",&n,&m,&s,&e,&ti);
        for (int i=1;i<=m;i++) {
        int x,y;
        scanf("%d%d ",&x,&y);
        x++;y++;
        b[x][y]=b[y][x]=1;
        }
        scanf("%d",&fn);
        for (int i=1;i<=fn;i++) {
        scanf("%d",&t[i]);
        for (int j=1;j<=t[i];j++) {scanf("%d",&a[i][j]);a[i][j]++;   }
        }
        for (int i=1;i<=n;i++) f[i][i][0]=1;
        for (int i=1;i<=12;i++)
        for (int j=1;j<=n;j++)
            for (int k=1;k<=n;k++){
            for (int l=1;l<=n;l++)
                if (f[j][l][i-1]&&b[l][k]) (f[j][k][i]+=f[j][l][i-1])%=mod;    
            for (int l=1;l<=fn;l++)
                if (a[l][i%t[l]+1]==k) {f[j][k][i]=0;}
            }
        mat x,y;
        x.n=x.m=y.n=y.m=n;
        for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            x.a[i][j]=f[i][j][12];
        x=power(x,ti/12);
        for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            y.a[i][j]=f[i][j][ti%12];
        x=x*y;
        printf("%d",x.a[s+1][e+1]);
        return 0;
    }
  • 相关阅读:
    nagios监控oracle 表空间
    Oracle报错,ORA-28001: 口令已经失效
    存储基本知识【转载】
    通过shell查找访问日志中访问量最大的ip
    《Java程序设计》 第二周学习任务
    IntelliJ IDEA 激活
    破解某绝地和某DNF辅助
    SMMS:一个不错的免费图床
    Linux使用ASF云挂卡(挂游戏时长)
    Centos7手动编译安装apache
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4348962.html
Copyright © 2011-2022 走看看