zoukankan      html  css  js  c++  java
  • SGU 131 贴地砖类型 状态压缩DP

    用dp[i][j]表示要贴第i层时,第i-1层的状态, 然后每一层dfs枚举一下情况即可
    dfs(x, y, pre, now) x层数 y枚举的当前列 pre 前一层状态, now当前层状态


    根据当前列y的这位上pre和now状态,确定要贴的图形, 注意贴完以后pre层必须满状态,在贴的过程中处理必须优先把pre层贴满。


    状态转移如下图:.表示空,*表示满


    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    #define LL long long
    int n, m;
    LL dp[11][1<<9];
    int f(int a) {
    	return 1<<a;
    }
    LL cnt;
    int N;
    void dfs(int x, int y, int pre, int now) {
    	if(y >= m) {
    		dp[x+1][now] += cnt;
    		return;
    	}
    	if( pre&f(y) && now&f(y)) {
    	    dfs(x, y+1, pre, now);
    	    return;
    	}
    	if( !(pre&f(y)) && !(now&f(y)) ) {
    	    dfs(x, y+1, pre|f(y), now|f(y)); //*
    	    if(y+1 < m) {                    //*
                if( !(now&f(y+1)) )                         //*
                    dfs(x, y+1, pre|f(y), now|f(y)|f(y+1)); //**
    
                if( !(pre&f(y+1)) )                         //**
                    dfs(x, y+1, pre|f(y)|f(y+1), now|f(y)); //*
    
                if( !(pre&f(y+1)) && !(now&f(y+1)) )          //**
                    dfs(x, y+1, pre|f(y)|f(y+1), now|f(y+1)); // *
    	    }
    	    return;
    	}
    	if( pre&f(y) && !(now&f(y)) ) {
    	    if( y+1 < m && !(now&f(y+1)) )                 //*
                dfs(x, y+1, pre|f(y), now|f(y)|f(y+1));    //**
    
    	    if( y+1 < m && !(pre&f(y+1)) && !(now&f(y+1)) )    // *
                dfs(x, y+1, pre|f(y+1), now|f(y)|f(y+1));      //**
    	    dfs(x, y+1, pre, now); // 不放
    	    return;
    	}
    	if( !(pre&f(y)) && now&f(y)) {
    	    if(y+1 < m && !(pre&f(y+1) && !(now&f(y+1))) ) //**
                dfs(x, y+1, pre|f(y)|f(y+1), now|f(y+1));  // *
    	}
    
    }
    int main() {
    	int i, j;
    	while(~scanf("%d%d", &n, &m)) {
    		N = 1<<m;
    		memset(dp, 0, sizeof(dp));
    		dp[0][N-1] = 1;
    		for(i = 0; i < n; i++)
    			for(j = 0; j < N; j++) if(dp[i][j]) {
    				cnt = dp[i][j];
    				dfs(i, 0, j, 0);
    			}
    		cout << dp[n][N-1] << endl;
    	}
    }
    /*
    2 3
    5
    
    9 9
    38896105985522272
    
    6 6
    5350806
    */
    


  • 相关阅读:
    0916 编程实验一 词法分析程序 总结
    0916 编程实验一 词法分析程序
    0909编译
    C语言文法
    词法分析编译感想
    词法分析
    0909 编译原理
    0429团队3.0
    0428 团队项目合作2.0作业
    0422 数学口袋精灵app
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2999697.html
Copyright © 2011-2022 走看看