zoukankan      html  css  js  c++  java
  • POJ3254或洛谷1879 Corn Fields

    一道状压(DP)

    POJ原题链接

    洛谷原题链接

    很显然的状压,(1)表示种植,(0)表示荒废。
    将输入直接进行状压,而要满足分配的草场是适合种草的土地,即是分配时的状态中的(1),在输入对应的状态中也是(1),而(0)对应(0,1)都可以。
    设输入的这行状态为(a[i]),分配时的这行状态为(x),则用位运算来表示上述条件即((sim a[i])&x=0),设其为函数(judge(i,x))
    因为每个草场不能相邻,对于每一行,可以先预处理出在二进制下没有(1)是相邻的所以数,记录在集合(S)中,集合大小为(l);对于列上要求不相邻,即上下两行不能有(1)相邻,即(i&(i-1)=0)
    定义(f[i][j])表示分配至第(i)行,第(i)行的状态为(j)

    (qquadqquad f[i][j]=sumlimits_{k=0,judge(i-1,S[k]) ext{且}i&(i-1)=0}^{l-1}f[i-1][k], ext{其中}i,j ext{满足}judge(i,S[j]))

    最终结果即是(sumlimits_{i=0}^{l-1}f[n][i])
    另外,在(DP)时记得对(10^9)进行取模。

    #include<cstdio>
    using namespace std;
    const int N = 13;
    const int M = 400;
    const int mod = 1e9;
    int f[N][M], a[N], S[M];
    int re()
    {
    	int x = 0;
    	char c = getchar();
    	bool p = 0;
    	for (; c<'0' || c>'9'; c = getchar())
    		p = (c == '-' || p) ? 1 : 0;
    	for (; c >= '0'&&c <= '9'; c = getchar())
    		x = x * 10 + (c - '0');
    	return p ? -x : x;
    }
    bool judge(int x, int y)
    {
    	if ((~a[x]) & y)
    		return false;
    	return true;
    }
    int main()
    {
    	int i, j, n, m, l = 0, k, o;
    	n = re();
    	m = re();
    	o = 1 << m;
    	for (i = 1; i <= n; i++)
    		for (j = 1; j <= m; j++)
    			a[i] |= (re() << (m - j));
    	for (i = 0; i < o; i++)
    		if (!(i&(i << 1)))
    			k = S[l++] = i;
    	f[0][0] = 1;
    	for (i = 1; i <= n; i++)
    		for (j = 0; j < l; j++)
    			if (judge(i, S[j]))
    				for (k = 0; k < l; k++)
    					if (judge(i - 1, S[k]) && !(S[j] & S[k]))
    						(f[i][j] += f[i - 1][k]) %= mod;
    	for (k = i = 0; i < l; i++)
    		(k += f[n][i]) %= mod;
    	printf("%d", k);
    	return 0;
    }
    
  • 相关阅读:
    scala与java的区别
    寒假第四天
    冲刺(第六天)
    冲刺(第五天)
    冲刺(第四天)
    冲刺(第三天)
    冲刺(第二天)
    第十周总结
    冲刺(第一天)
    文本中单词统计
  • 原文地址:https://www.cnblogs.com/Iowa-Battleship/p/9504654.html
Copyright © 2011-2022 走看看