zoukankan      html  css  js  c++  java
  • POJ 3254

    Magic Door

    题目大意:

    给一个地图,有障碍0,空地1,规定任意两头奶牛不能相邻且不能在障碍上面,问有多少种方法(一个都不放也算)。

    题目分析

    状态压缩: 首先将地图的每一行处理成用二进制表示Map[]。然后初始化每一行可能的情况(无用状态太多)存入State[].
    dp[i][S]表示考虑到第i行且第i行状态为S的方案数。

    [dp[i][S] += dp[i - 1][valid S'] ]

    中间进行些许剪枝(见代码)。

    code

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    
    const int N = 15, S = 40000, Mod = 100000000;
    int n, m;
    int Map[N];
    typedef long long ll;
    int state[S], scnt, ans;
    int dp[N][S];
    
    inline int DP(int u, int st){
    	if(u == 1) return dp[1][st] = 1;
    	if(dp[u][st] != -1) return dp[u][st];
    	int t = 0;
    	for(int i = 1; i <= scnt; i++){
    		if((state[i] & Map[u - 1]) || (state[i] & st)) continue;
    		t += DP(u - 1, state[i]);
    	}
    	return dp[u][st] = t;
    }
    
    int main(){
    	ios::sync_with_stdio(false);
    	cin.tie(NULL), cout.tie(NULL);
    	cin >> n >> m;
    	memset(dp, -1, sizeof dp);
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= m; j++){
    			int x; cin >> x;
    			if(!x) Map[i] |= (1 << (j - 1));
    		}
    	for(int s = 0; s < (1 << m); s++){
    		if(s & (s << 1)) continue;
    		state[++scnt] = s;
    	}
    	for(int i = 1; i <= scnt; i++){
    //		int s = state[i]; cout<<state[i]<<" ";
    //		while(s) cout<<s%2, s /= 2;cout<<endl;
    		if(state[i] & Map[n]) continue;
    		ans = (ans + DP(n, state[i])) % Mod;
    	}
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    【JAVA与C#比较】其它
    C#和java之间的一些差异与共性
    C#与Java的语法差异
    关于npm本地安装模块包(node_modules),安装不了的问题
    vue
    vue
    vue
    vue
    v
    vue -model
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7636274.html
Copyright © 2011-2022 走看看