poj3254

一道状态压DP题目。将每一行进行编码,1表示种0表示不种。首先求解出每一行合法的状态集合。对于第i行状态j,如果j&(j<<1)==0并且对于该行为0的地方j在当前位的二进制也是0,则表明状态j合法。用dp[i][j]表示第i行状态为j时(j合法的)的方法数,得到状态转移方程如下:

dp[i][j]=sum(dp[i-1][k]) j&k==0  ;在计算dp[i][j]时,可以枚举上一行的所有状态。

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<vector>
using namespace std;
int const SIZE = 13;
typedef long long LL;
const int mod = 100000000;
vector<int> vec[SIZE];  //保存第i行合法状态
int a[SIZE][SIZE];
LL dp[SIZE][1 << 13];
int bit[SIZE];
int m, n;
int main(){
	int i, j,k;
	bit[0] = 1;
	for (i = 1; i < SIZE; i++)
		bit[i] = bit[i - 1] * 2;
	while (~scanf("%d%d", &n, &m)){
		for (i = 1; i <= n;i++)
		for (j = 1; j <= m; j++)
			scanf("%d", &a[i][j]);
		for (i = 0; i <= n; i++)
			vec[i].clear();    //初始化清空
		//计算每一行合法状态并保留在vec中
		vec[0].push_back(0);
		for (i = 1; i <= n; i++){
			for (j = 0; j < bit[m]; j++){
				if ((j&(j << 1)))
					continue;
				for (k = 1; k <= m; k++){
					if ((a[i][k] == 0) && (bit[k - 1] & j)!= 0)
						break;
				}
				if (k == m + 1)
					vec[i].push_back(j);
			}
		}
		memset(dp, 0, sizeof(dp));
		dp[0][0] = 1;//0块土地时候什么也不种,也是一种方法
		for (i = 1; i <= n; i++){
			for (j = 0; j < (int)vec[i].size(); j++){
				for (k = 0; k < (int)vec[i - 1].size(); k++){
					if (!(vec[i - 1][k] & vec[i][j])){   //状态相容
						dp[i][j] += dp[i - 1][k];
						dp[i][j] %= mod;
					}
				}
			}
		}
		LL ans = 0;
		for (i = 0; i < (int)vec[n].size(); i++){
			ans += dp[n][i];
			ans %= mod;
		}
		printf("%I64d\n", ans);
	}
	return 0;
}

  

时间: 2024-11-06 03:54:06

poj3254的相关文章

POJ3254 Corn Fields 状态压缩DP

题目大意是在一块M行N列的农场上种谷物,但是不希望彼此相邻(共用一条边),并且有些地方不能种植谷物,给定M,N(范围都不超过12)以及一些不能种谷物的位置,求出一共有多少种方法种谷物. 状态压缩DP,设dp(i, k) 为种到第i行时,第i行状态为k的总共方案数,可以知道dp(i, k) = ∑dp(i -1, k'),其中我们要判断彼此相邻的情况以及不能种植的情况即可. #include <stdio.h> #include <vector> #include <math.

【poj3254】 Corn Fields

http://poj.org/problem?id=3254 (题目链接) 题意 给出一块n*m的田地,有些能够耕种,有些不能.要求将牛两两不相邻的放在田中,牛的个数至少为1个.问有多少种放法. Solution 状压dp水题. f[i][j]表示第i行状态为j时,前i行的总方案数. 代码 // poj3254 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring>

poj3254 Corn Fields (状压DP)

http://poj.org/problem?id=3254 Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7588   Accepted: 4050 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parc

poj3254(Corn Fields)状压dp

题意:在n*m(1<=n,m<=12)的矩阵上种植玉米,任意共边的方格不能同时种,并且有些特定方格也不能种.问能有多少种种植的方案: 解法:很经典的状压模型.先将每一行的合法状态求出来,12的时候最多377个合法状态.然后进行与行之间的状态转移.最坏复杂度12*(377^2) 代码: /**************************************************** * author:xiefubao **********************************

POJ3254 状压DP入门

题目:http://poj.org/problem?id=3254 因为&运算写成&&--导致调试了快一个小时代的代码没有搞定 关于建图: 1.题目中是1表示可以放牧,0表示不可以放牧,但是建图的时候,可以放牧的位用0表示,不可以放牧的位用1表示.原因如下: 假设可以放牧的位用1表示,不可以放牧的位用0表示,那么假设当前行状态时1010   想要放置1001 ,&运算的结果是1,但是显然不合法, 也就是说  设值状态的意义,以及怎么判断是不是合法,这个在做之前一定考虑清楚再

POJ3254:Corn Fields(状态压缩)

Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a number of squares. Regrettably, some of the squares are infertile and

[poj3254]Corn Fields_状压dp

Corn Fields poj3254 题目大意:给你一个n*m的地,每一块地可以种或不种,两块种过的地不能挨着,可以一块都不种,问所有的种地方案数. 注释:读入用0和1,1<=n,m<=12. 想法:这题和炮兵阵地特别像,比炮兵更简单.我们再度入的时候直接处理出当前行的地的不可种的情况.预处理出一行如果都能种的话所可能的方案数.此处需要满足的就是两块地不能挨着,通过打表我们可以发现这种情况最多只有377种情况(我们附上打表用的程序) #include <iostream> #in

状压dp入门第一题 poj3254

题目链接 http://poj.org/problem?id=3254 转自http://blog.csdn.net/harrypoirot/article/details/23163485 1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <iostream> 6 #include <sstream

poj3254:基础状压dp

第二个状压dp 做过的第一个也是放牛问题,两头牛不能相邻 这个题多了一个限制,就是有些位置不能放牛 于是先与处理一下每一行所有不能放牛的状态,处理的过程直接对每一个不能放牛的状态或以下 ac代码: #include <iostream> #include <stdio.h> #include<string.h> #include<algorithm> #include<string> #include<ctype.h> using n

轮廓线DP POJ3254

补了一发轮廓线DP,发现完全没有必要从右往左设置状态,自然一点: 5 6 7 8 9 1 2 3 4 如此设置轮廓线标号,转移的时候直接把当前j位改成0或者1就行了.注意多记录些信息对简化代码是很有帮助的,尤其对于我这种代码经常错的一塌糊涂的人来说.. 呆马: #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath>