玉米田
思路:和小国王的思路差不多,判断状态,预处理状态,进行转移dp
代码:
#include <iostream>
#include <vector>
using namespace std;
const int N = 15,M = 1<<N,mod = 1e8;
int f[N][M];
int a[N];
int n,m;
vector<int> state,head[M];
bool check(int x){
return !(x & x<<1);
}
int main() {
cin>>n>>m;
for(int i = 1;i<=n;i++){
int res = 0;
int x = 1;
for(int j = 0;j<m;j++){
int t ;
scanf("%d",&t);
if(t==0){
res += x;
}
x*=2;
}
a[i] = res;
}
for(int i = 0;i< 1<<m;i++){
if(check(i)) state.push_back(i);
}
for(int i = 0;i<state.size();i++){
for (int j = 0; j < state.size(); ++j) {
if((state[i]&state[j]) == 0)
head[i].push_back(j);
}
}
f[0][0] = 1;
for(int i = 1;i<=n+1;i++){
for(int j = 0;j< state.size();j++){
for(auto k : head[j]){
if((state[j]&a[i])) continue;
f[i][j] = (f[i][j]+f[i-1][k])%mod;
}
}
}
cout<<f[n+1][0];
return 0;
}
简化版思路(改了一点来自别人的:
#include <iostream>
#include <vector>
using namespace std;
const int N = 15,M = 1<<N,mod = 1e8;
int f[N][M];
int a[N];
int n,m;
vector<int> state,head[M];
bool check(int x){
return !(x & x<<1);
}
int main() {
cin>>n>>m;
for(int i = 1;i<=n;i++){
for(int j = 0;j<m;j++){
int t ;
scanf("%d",&t);
a[i] += !t<<j;
}
}
for(int i = 0;i< 1<<m;i++){
if(check(i)) state.push_back(i);
}
for(int i = 0;i<state.size();i++){
for (int j = 0; j < state.size(); ++j) {
if((state[i]&state[j]) == 0)
head[i].push_back(j);
}
}
f[0][0] = 1;
for(int i = 1;i<=n+1;i++){
for(int j = 0;j< state.size();j++){
for(auto k : head[j]){
if((state[j]&a[i])) continue;
f[i][j] = (f[i][j]+f[i-1][k])%mod;
}
}
}
cout<<f[n+1][0];
return 0;
}