zoukankan      html  css  js  c++  java
  • P2233 [HNOI2002]公交车路线

    题目背景

    在长沙城新建的环城公路上一共有8个公交站,分别为A、B、C、D、E、F、G、H。公共汽车只能够在相邻的两个公交站之间运行,因此你从某一个公交站到另外一个公交站往往要换几次车,例如从公交站A到公交站D,你就至少需要换3次车。

    Tiger的方向感极其糟糕,我们知道从公交站A到公交E只需要换4次车就可以到达,可是tiger却总共换了n次车,注意tiger一旦到达公交站E,他不会愚蠢到再去换车。现在希望你计算一下tiger有多少种可能的乘车方案。

    题目描述

    输入输出格式

    输入格式:

    输入文件由bus.in读入,输入文件当中仅有一个正整数n(4<=n<=10000000),表示tiger从公交车站A到公交车站E共换了n次车。

    输出格式:

    输出到文件bus.out。输出文件仅有一个正整数,由于方案数很大,请输出方案数除以 1000后的余数。

    输入输出样例

    输入样例#1: 
    6
    输出样例#1: 
    8

    说明

    8条路线分别是:

    (A→B→C→D→C→D→E),(A→B→C→B→C→D→E),

    (A→B→A→B→C→D→E),(A→H→A→B→C→D→E),

    (A→H→G→F→G→F→E),(A→H→G→H→G→F→E),

    (A→H→A→H→G→F→E),(A→B→A→H→G→F→E)。

    Solution:

      本题简单矩阵加速dp。

      首先,一个很显然的dp是定义状态$f[i][j]$表示到了$i$点走了$j$步的方案数,则$f[i][j]=f[i-1][j-1]+f[i+1][j-1]$,注意的是$F ightarrow E$和$D ightarrow E$都是单向转移的。

      这样显然时空都会炸,空间还好解决,转移时直接滚掉第2维。

      时间上我们发现可以去掉$E$点改为统计$F,D$的方案数,而方案数是对称的,于是只需要统计一边的4个点的方案就好了。

      这样去直接dp是可以过的。

      但是还可以优化,根据优化后的4个点的dp转移构造矩阵

        初始矩阵:$[1,0,0,0]$,中间矩阵:$egin{bmatrix}
     0& 1& 0& 0\
     2& 0& 1& 0\
     0& 1& 0& 1\
     0& 0& 1& 0
    end{bmatrix}$

      最后答案就是$A[1,4]*2$啦。

    代码:

    /*Code by 520 -- 9.11*/
    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define RE register
    #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
    #define Clr(p) memset(&p,0,sizeof(p))
    using namespace std;
    const int mod = 1e3;
    int n;
    struct matrix{int a[4][4],r,c;};
    
    il matrix Mul(matrix x,matrix y){
        matrix tp; Clr(tp);
        tp.r=x.r,tp.c=y.c;
        For(i,0,3) For(j,0,3) For(k,0,3)
            tp.a[i][j]=(tp.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
        return tp;
    }
    
    il void solve(int k){
        matrix tp,ans; Clr(tp),Clr(ans);
        ans.r=1,ans.c=tp.r=tp.c=4;
        ans.a[0][0]=ans.a[1][1]=ans.a[2][2]=ans.a[3][3]=1;
        tp.a[1][0]=2,tp.a[0][1]=tp.a[1][2]=tp.a[2][1]=tp.a[2][3]=tp.a[3][2]=1;
        while(k){
            if(k&1) ans=Mul(ans,tp);
            k>>=1;
            tp=Mul(tp,tp);
        }
        printf("%d
    ",2*ans.a[0][3]%mod);
    }
    
    int main(){
        cin>>n;
        solve(n-1);
        return 0;
    }
  • 相关阅读:
    rabbitmq集群几个比较好的文章
    rabbitmq集群步骤
    rabbitmq安装
    查找出系统中大于50k 且小于100k 的文件并删除。
    现将文件a.txt 中的所有abc 替换成def
    统计/var/log/下有多少文件
    压缩解压目录结构不能改变
    chkconfig命令
    linux运维必须掌握
    三剑客
  • 原文地址:https://www.cnblogs.com/five20/p/9632982.html
Copyright © 2011-2022 走看看