本文主要是介绍327. 玉米田 (棋盘状压dp),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
分析:
限制条件:由于不能有公共边缘,并且只有在肥沃的土地上才可以种植,那么必须满足下面三种限制条件
- 只能在肥沃的土地上种 不能 x>>i&1 && a[i][line]==0
- 同一列 不能连续种植 不能 x>>i&1 x>>i+1&1
- 同一行 不能连续种植 a&b==0
初始化:0
边界:dp[0][0]=1
比较直观的is_valid()方法
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N=13,M=1<<N;
const int mod=1e8;
int n,m;
int a[N][N];
int dp[N][M];
vector<int> state;
bool check(int x)
{for(int i=0;i<n;i++)if((x>>i&1)&&(x>>(i+1)&1)) return false;return true;
}bool is_valid(int x,int line)
{for(int i=0;i<n;i++)if(x>>i&1 && a[i][line]==0)return false;return true;
}int main()
{cin>>n>>m;for(int i=0;i<n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];for(int i=0;i<1<<n;i++)if(check(i))state.push_back(i);dp[0][0]=1;for(int i=1;i<=m+1;i++)for(int j=0;j<state.size();j++)for(int k=0;k<state.size();k++){int a=state[j],b=state[k];if(is_valid(a,i)&&(a&b)==0)dp[i][a]=(dp[i][a]+dp[i-1][b])%mod;}cout<<dp[m+1][0]<<endl;return 0;
}
二进制存储土地状态的方法
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N=14,M=1<<N;
const int mod=1e8;
int n,m;
int g[M];
int dp[N][M];
vector<int> state;
bool check(int x)
{for(int i=0;i<m;i++)if((x>>i&1)&&(x>>(i+1)&1)) return false;return true;
}int main()
{cin>>n>>m;for(int i=1;i<=n;i++)for(int j=0;j<m;j++){int a;cin>>a;g[i]+=(a==0)?1<<j:0;}for(int i=0;i<1<<m;i++)if(check(i))state.push_back(i);dp[0][0]=1;for(int i=1;i<=n+1;i++)for(int j=0;j<state.size();j++)for(int k=0;k<state.size();k++){int a=state[j],b=state[k];if((a&b)==0&&(g[i]&a)==0)dp[i][a]=(dp[i][a]+dp[i-1][b])%mod;}cout<<dp[n+1][0];return 0;
}
这篇关于327. 玉米田 (棋盘状压dp)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!