• [HNOI2010]公交线路


    [HNOI2010]公交线路

    不看题解不会做类型...
    看到数据范围,显然要构造矩阵.
    但是状态有那么多,于是要缩减状态.
    (dp[i][s])表示第i个车站和之后的p个车站,k辆车最后出没的位置.一辆车最多走p个车站,于是必定会在这p个车站出现至少一次,j就是一个长度为p的,含k个1的01串,最多有252种情况,转移只要在1之间转移就可以了,所以显然第一位没有车的状态可以缩掉.
    每次转移只动一辆车,这样一步一步地走,不重不漏.转移矩阵构出来之后直接快速幂就可以了,最后要的状态是(dp[n-k][(1<<k)-1])

    #include<bits/stdc++.h>
    #define mod 30031
    using namespace std;
    int n,k,p,s,f[20],st[505];
    int lowbit(int x){return x&-x;}
    int calc(int x){int r=0;for(int i=x;i>=1;i-=lowbit(i),r++);return r;}
    struct matrix
    {
        int a[150][150];
        int *operator [] (int i){return a[i];}
        matrix operator * (matrix x)
            {
                matrix y;memset(y.a,0,sizeof(y.a));
                for(int i=1;i<=s;i++)
                    for(int j=1;j<=s;j++)
                        for(int k=1;k<=s;k++)
                            y[i][j]+=a[i][k]*x[k][j]%mod,y[i][j]%=mod;
                return y;
            }
    }A,B;
    void ksm(int k)
    {
        for(int i=1;i<=s;i++)A[i][i]=1;
        while(k){if(k&1)A=A*B;k>>=1;B=B*B;}
    }
    int main()
    {
        cin>>n>>k>>p;//状态记录的是k辆车在i往后p个站点的最后出没点
        for(int i=0;i<(1<<p);i++)//合法状态是第1个位置有车,区间里一定是k个最后出没点
            if(calc(i)==k&&(i&1))st[++s]=i;
        for(int i=1;i<=s;i++)
            for(int j=1;j<=s;j++)
                if(calc((st[i]>>1)&st[j])==k-1)B[i][j]=1;
        ksm(n-k);
        cout<<A[1][1]<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    cull/clip distance example
    Sutherland-Hodgeman多边形裁剪
    OpenCV 脸部跟踪(3)
    人脸识别中的Procruster analysis应用
    卡尔曼滤波的原理说明
    偏导数
    泊松分布E(X^2)
    抽奖概率
    卡尔曼滤波的原理说明
    卡尔曼滤波3
  • 原文地址:https://www.cnblogs.com/terribleterrible/p/9833630.html
Copyright © 2020-2023  润新知