zoukankan      html  css  js  c++  java
  • 某考试 T1 line

    状压dp+矩阵转移,据说正解是dfs出的合法状态,,但难道不是三个for就行了吗2333

    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #define ll long long
    const int ha=1000000007;
    using namespace std;
    int C[12][12],n,P,Q,cnt;
    struct node{
    	int a[3],full;
    }zt[233];
    
    inline int add(int x,int y){
    	x+=y;
    	return x>=ha?x-ha:x;
    }
    
    struct matrix{
    	int a[199][199];
    	
    	inline void clear(){
    		memset(a,0,sizeof(a));
    	}
    	
    	matrix operator *(const matrix &u)const{
    		matrix r;
    		r.clear();
    		for(int k=1;k<=cnt;k++)
    		    for(int i=1;i<=cnt;i++)
    		        for(int j=1;j<=cnt;j++) r.a[i][j]=add(r.a[i][j],a[i][k]*(ll)u.a[k][j]%ha);
    		
    		return r;
    	}
    }base,ANS;
    
    inline void init(){
    	C[0][0]=1;
    	for(int i=1;i<=8;i++){
    	    C[i][0]=1;
    	    for(int j=1;j<=i;j++) C[i][j]=add(C[i-1][j-1],C[i-1][j]);
    	}
    }
    
    inline void can(int i,int j){
    	node x=zt[i],y=zt[j];
    	if(y.a[1]<=x.a[0]&&y.a[2]<=x.a[1]&&x.full+(y.a[1]+y.a[2]==n?1:0)==y.full){
    		base.a[i][j]=C[x.a[0]][y.a[1]]*(ll)C[x.a[1]][y.a[2]]%ha;
    	}
    }
    
    inline void build(){
    	for(int i=n;i>=0;i--)
    	    for(int j=(P==2?0:n-i);j>=0;j--)
    	            for(int l=0;l<=Q;l++) zt[++cnt]=(node){i,n-i-j,j,l};
    	
    	base.clear();
    	for(int i=1;i<=cnt;i++)
    	    for(int j=1;j<=cnt;j++) can(i,j);
    }
    
    inline void solve(ll y){
    	ANS.clear();
    	for(int i=1;i<=cnt;i++) ANS.a[i][i]=1;
    	int ans=0;
    	for(;y;y>>=1,base=base*base) if(y&1) ANS=ANS*base;
    	/*
    	for(int i=1;i<=cnt;i++){
    		for(int j=1;j<=cnt;j++) printf("%d ",ANS.a[i][j]);
    		puts("");
    	}
    	*/
    	for(int i=1;i<=cnt;i++) ans=add(ans,ANS.a[1][i]);
    	printf("%d
    ",ans);
    }
    
    int main(){
    //	freopen("line.in","r",stdin);
    //	freopen("line.out","w",stdout);
    	
    	init();
    	ll m;
    	scanf("%d%lld%d%d",&n,&m,&P,&Q);
    	if(P==1){
    		puts("1");
    		return 0;
    	}
    	
    	build();
    	solve(m);
    	
    	return 0;
    }
    

      

  • 相关阅读:
    GDUFE ACM-1093
    GDUFE ACM-1088
    GDUFE ACM-1069
    GDUFE ACM-1051
    GDUFE ACM-1049
    GDUFE ACM-1046
    GDUFE ACM-1045
    GDUFE ACM-1043
    OpenCV学习(7.12)
    OpenCV学习(7.11)
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8590300.html
Copyright © 2011-2022 走看看