zoukankan      html  css  js  c++  java
  • HDU 5434

    其实是一道状态DP题。都是行与行之间的转移,可以知道,当某j列中有一个象,如果存在情况i-1行j-1列有象而i,j-1位置无象则不可放,或者i-1,j+1有而i,j+1无同样不可放。

    使用快速状态转移

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    
    using namespace std;
    
    const int mod=1000000007;
    const int MAX=(1<<7);
    int TranMatrix[MAX][MAX];
    int tmp[MAX][MAX];
    /*
    int mul(int a,int b){
    	int res=0;
    	while(b){
    		if(b&1) res=(res+a)%mod;
    		a=(a+a)%mod;
    		b>>=1;
    	}
    	return res;
    }
    */
    int quick(int Status,int n){
    	int ans[MAX][MAX],for_save[MAX][MAX];
    	memset(ans,0,sizeof(ans));
    	for(int i=0;i<MAX;i++) ans[i][i]=1;
    	while(n){
    		if(n&1){
    			for(int i=0;i<Status;i++){
    				for(int j=0;j<Status;j++){
    					for_save[i][j]=0;
    					for(int k=0;k<Status;k++){
    						for_save[i][j]=(for_save[i][j]+1LL*ans[i][k]*tmp[k][j]%mod);
    						if(for_save[i][j]>mod) for_save[i][j]-=mod;
    					}
    				}
    			}
    			for(int i=0;i<Status;i++){
    				for(int j=0;j<Status;j++)
    					ans[i][j]=for_save[i][j];
    			}
    		}
    		n>>=1;
    		for(int i=0;i<Status;i++){
    			for(int j=0;j<Status;j++){
    				for_save[i][j]=0;
    				for(int k=0;k<Status;k++){
    					for_save[i][j]=(for_save[i][j]+1LL*tmp[i][k]*tmp[k][j]%mod);
    					if(for_save[i][j]>mod) for_save[i][j]-=mod;
    				}
    			}
    		}	
    		for(int i=0;i<Status;i++){
    			for(int j=0;j<Status;j++)
    				tmp[i][j]=for_save[i][j];
    		}
    	}
    	int res=0;
    	for(int i=0;i<Status;i++)
    		res=(res+ans[0][i])%mod;
    	return res;
    }
    
    int main(){
    	int n,m;
    	int Status=(1<<7);
    	for(int i=0;i<(Status);i++){
    		for(int j=0;j<Status;j++){
    			bool flag=true;
    			for(int k=0;k<7;k++){
    				if((((1<<k)&j)==(1<<k))&&(((1<<k)&i)==0)){
    					if((((1<<(k+1))&j)==0)&&(((1<<(k+1))&i)>0)){
    						flag=false;
    						break;
    					}
    					else if(k>0&&((1<<(k-1))&j)==0&&(((1<<(k-1))&i)>0)){
    						flag=false;
    						break;
    					}
    				}
    			}
    			TranMatrix[i][j]=flag?1:0;
    		}
    	}
    	while(scanf("%d%d",&n,&m)!=EOF){
    		//swap(n,m);
    		Status=1<<m;
    		for(int i=0;i<Status;i++){
    			for(int j=0;j<Status;j++)
    				tmp[i][j]=TranMatrix[i][j];
    		}
    		printf("%d
    ",quick(Status,n));
    		
    	}
    	return 0;
    }
    

    矩阵可过。

  • 相关阅读:
    【车】平安车险费用
    【光环国际】掌握项目经理12个工作流程
    【光环国际】500强公司7个项目管理工具
    数据仓库和商业智能演进五个阶段
    【技术与商业案例解读笔记】095:Google大数据三驾马车笔记
    15道最常考的SpringBoot面试题,你都遇到过哪些?
    用户画像4:标签数据开发
    plsql 传参
    shell专题(二):Shell解析器
    shell专题(三):Shell脚本入门
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4816657.html
Copyright © 2011-2022 走看看