zoukankan      html  css  js  c++  java
  • $[TJOI2017]$ 可乐 矩阵优化$dp$

    (Sol)

    (f_i)为到第(i)秒的方案数,显然(f_i=)在第(i)秒前爆炸的方案数+在第(i)秒爆炸的方案数+在第(i)秒停下的方案数+在第(i)秒走向下一个城市

    的方案数.注意到第四个转移和当前在哪个城市有关,所以要另记一维(j)表示当前位置.于是(f_{i,j}=)(i)秒前在(j)爆炸的方案数+第(i)秒在(j)爆炸的方案数+第(i)秒停在(j)的方案数+第(i)秒由别的城市走向(j)的方案数.记这四个量分别为(f1,f2,f3,f4).

    (f1_{i,j}=f1_{i-1,j}+f2_{i-1,j})

    (f2_{i,j}=f3_{i-1,j}+f4_{i-1,j})

    (f3_{i,j}=f3_{i-1,j}+f4_{i-1,j})

    (f4_{i,j}=f3_{i-1,k}+f4_{i-1,k}),其中,(k)(j)的相邻城市.

    这样瞎(dp)一下就可以获得(20pts)的好成绩(QAQ).

    其实上面的转移方程看起来就很矩阵优化的亚子,于是矩阵优化一下就好辣.

    (Code)

    #include<bits/stdc++.h>
    #define il inline
    #define Ri register int
    #define go(i,a,b) for(Ri i=a;i<=b;++i)
    #define yes(i,a,b) for(Ri i=a;i>=b;--i)
    #define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define db double
    #define inf 2147483647
    using namespace std;
    il int read()
    {
        Ri x=0,y=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        return x*y;
    }
    const int mod=2017;
    int n,m,t,as;
    vector<int>to[31];
    struct mt
    {
        int a[121][121];bool ste;
        il void clear(){mem(a,0);ste=0;}
    }trs,cur;
    il void inc(Ri &x,Ri y){x+=y;if(x>=mod)x-=mod;}
    il mt operator * (mt x,mt y)
    {
        mt z;z.clear(),z.ste=x.ste;Ri h=x.ste?1:n*4;
        go(i,1,h)
    	go(j,1,n*4)
    	go(k,1,n*4)
    	inc(z.a[i][j],1ll*x.a[i][k]*y.a[k][j]%mod);
        return z;
    }
    il void init()
    {
        trs.clear();
        go(i,1,n)
        {
    	    Ri mi=(i-1)*4+1;
    	    trs.a[mi][mi]=trs.a[mi+1][mi]=1;
    	    trs.a[mi+2][mi+1]=trs.a[mi+3][mi+1]=1;
    	    trs.a[mi+2][mi+2]=trs.a[mi+3][mi+2]=1;
        	    go(j,0,(int)to[i].size()-1){Ri k=(to[i][j]-1)*4+3;trs.a[k][mi+3]=trs.a[k+1][mi+3]=1;}
        }
    }
    int main()
    {
        n=read(),m=read();
        go(i,1,m){Ri u=read(),v=read();to[u].push_back(v),to[v].push_back(u);}
        init();cur.clear();cur.a[1][3]=1,cur.ste=1;
        t=read();
        while(t){if(t&1)cur=cur*trs;trs=trs*trs;t>>=1;}
        go(i,1,n*4)inc(as,cur.a[1][i]);
        printf("%d
    ",as);
        return 0;
    }
    
    
  • 相关阅读:
    python模块的作用和说明
    Python列表推导式和嵌套的列表推导式
    Python数据结构 将列表作为栈和队列使用
    Python解包参数列表及 Lambda 表达式
    Python函数标注
    Python range() 函数
    python序列和其它类型的比较
    Python教程 深入条件控制
    02爬虫requests请求库
    1
  • 原文地址:https://www.cnblogs.com/forward777/p/11741808.html
Copyright © 2011-2022 走看看