• LG P1879 [USACO06NOV]Corn Fields G


    题目描述

    农场主John新买了一块长方形的新牧场,这块牧场被划分成(m)(n)列((1 ≤ m ≤ 12); (1 ≤ n ≤ 12)),每一格都是一块正方形的土地。John打算在牧场上的某几格里种上美味的草,供他的奶牛们享用。
    遗憾的是,有些土地相当贫瘠,不能用来种草。并且,奶牛们喜欢独占一块草地的感觉,于是John不会选择两块相邻的土地,也就是说,没有哪两块草地有公共边。
    John想知道,如果不考虑草地的总块数,那么,一共有多少种种植方案可供他选择?(当然,把新牧场完全荒废也是一种方案)

    分析

    (s_i)为第(i)行土地的状态,对于其第(j)位,当这块土地适合种草时为(0),不适合种草时为(1)

    用二进制状态(j)表示某一行种草的情况,某一位为(1)表示种草,否则不种。

    当然,对于一个状态(j),它自身必须是合法的,即不存在相邻两位都为(1),可以表示为:(forall 0le ile n-2)((jgg i)&1=0)((jgg (i-1))&1=0)。用(O(2^n))的时间处理出满足条件的状态集合(S)

    (f(i,j))当前在处理第(i)行,且改行状态为(j)时的方案数。显然,只需考虑(S)内的状态(j)即可。枚举前一行的状态(k),那么要有(j&k=0),即上下土地不能相邻。另一方面,(j,k)本身对于第(i,i-1)行也应当是合法的,即(j&s_i=0)(k&s_{i-1}=0),表示没有草种在不能种草的土地上。

    综上所述,

    [f(i,j)leftarrow sum_{kin S,k&j=0,k&s_{i-1}=0}f(i-1,k), j&s_i=0,jin S ]

    边界条件(f(0,0)=1),答案即为(sumlimits_{jin S}f(m,j))。预处理复杂度(O(2^n)),转移复杂度(O(m|S|^2)),统计复杂度(O(|S|))。事实上(|S|)较小。

    Code

    #include <cstdio>
    #include <iostream>
    
    using namespace std;
    
    const int Maxn=(1<<12)+3;;
    const int Maxm=13;
    const int Mod=1e9;
    
    int f[Maxm][Maxn],s[Maxm],g[Maxn],g_cnt;
    int n,m;
    
    inline bool valid(int j)
    {
    	for(int i=0;i<(n-1);++i)
    		if(((j>>i)&1)&&((j>>(i+1))&1))
    			return false;
    	
    	return true;
    }
    
    int main()
    {
    	scanf("%d%d",&m,&n);
    	
    	for(int i=1;i<=m;++i)
    	{
    		int S=0;
    		
    		for(int j=0,k;j<n;++j)
    			scanf("%d",&k),
    			(!k)&&(S|=1<<j);
    		
    		s[i]=S;
    	} 
    	
    	for(int i=0;i<(1<<n)-1;++i)
    		if(valid(i))
    			g[++g_cnt]=i;
    	
    	f[0][0]=1;
    	
    	for(int i=1;i<=m;++i)
    		for(int j=1;j<=g_cnt;++j)
    			for(int k=1;k<=g_cnt;++k)
    			{
    				int s1=g[j],s2=g[k];
    				
    				if(s1&s2||s1&s[i]||s2&s[i-1])
    					continue;
    				
    				f[i][s1]=(f[i][s1]+f[i-1][s2])%Mod;
    			}
    	
    	int ans=0;
    	
    	for(int j=1;j<=g_cnt;++j)
    		ans=(ans+f[m][g[j]])%Mod;
    	
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    工厂模式
    Bootstrap 日历
    处理乱码
    Eclipse常用快捷键
    C#_XML与Object转换
    jQuery选择函数
    Bootstrap如何正确引用字体图标
    js上拉加载、下拉刷新的插件
    js通用对象数组冒牌排序
    关于js跨域
  • 原文地址:https://www.cnblogs.com/Anverking/p/solution-lgp1879.html
Copyright © 2020-2023  润新知