状态压缩dp入门题目

来源:互联网 发布:数据挖掘模型分类 编辑:程序博客网 时间:2024/05/16 15:15

题目链接:http://poj.org/problem?id=3254

题目大意是有M×N的玉米地,但其中有些是不肥沃的,不能种植。用1来代表肥沃,0代表不肥沃。另外奶牛不喜欢挨着吃,也就是说要间隔着种植,求有几种种植方式,并将计算结果对1E8取模。
#include <iostream>#include <cstdio>using namespace std;int dp[12][1 << 12];    // dp[i][S] := 第i行的状态为S时的方法总数int bad[12];            // 荒地的maskint MOD = 100000000;int m, n;//************************************// Method:    dfs// FullName:  dfs// Access:    public // Returns:   void// Qualifier: 遍历一行// Parameter: int row y坐标// Parameter: int line x坐标// Parameter: int S 当前集合// Parameter: int except_S 排除集合(也就是上一行地的状态加上这一行荒地的状态)// Parameter: int pre_dp 上一行对应的个数//************************************void dfs(int row, int line, int S, int except_S, int pre_dp){   if (line == n)                              // 这一行种完了,统计结果   {      dp[row][S] = (dp[row][S] + pre_dp) % MOD;      return;   }   dfs(row, line + 1, S, except_S, pre_dp);    // 这一行还没有种完,继续尝试往下种   if (!(except_S & (1 << line)))  // 无重叠   {        // 这里的S | 1 << line将line加入集合,except_S | (1 << (line + 1))表示排除相邻的一个      dfs(row, line + 1, S | 1 << line, except_S | (1 << (line + 1)), pre_dp);   }}///////////////////////////SubMain//////////////////////////////////int main(int argc, char *argv[]){   cin >> m >> n;   for (int i = 0; i < m; ++i)   {      for (int j = 0; j < n; ++j)      {         int t;         cin >> t;         bad[i] |= (!t) << j;      }   }   dfs(0, 0, 0, bad[0], 1);   for (int i = 1; i < m; ++i)   {      for (int j = 0; j < (1 << n); ++j)      {         dfs(i, 0, 0, bad[i] | j, dp[i - 1][j]); // bad[i] | j表示上一行的状态j和这一行的荒地合并加入到排除集合中      }   }   int ans = 0;   for (int i = 0; i < (1 << n); ++i)   {      ans = (ans + dp[m - 1][i]) % MOD;   }   cout << ans << endl;   return 0;}


0 0