标签:lang == ++ main 分配 一个 c++ 输入 状态
农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形的土地。John打算在牧场上的某几格里种上美味的草,供他的奶牛们享用。
遗憾的是,有些土地相当贫瘠,不能用来种草。并且,奶牛们喜欢独占一块草地的感觉,于是John不会选择两块相邻的土地,也就是说,没有哪两块草地有公共边。
John想知道,如果不考虑草地的总块数,那么,一共有多少种种植方案可供他选择?(当然,把新牧场完全荒废也是一种方案)
输入输出格式
输入格式:
第一行:两个整数M和N,用空格隔开。
第2到第M+1行:每行包含N个用空格隔开的整数,描述了每块土地的状态。第i+1行描述了第i行的土地,所有整数均为0或1,是1的话,表示这块土地足够肥沃,0则表示这块土地不适合种草。
输出格式:
一个整数,即牧场分配总方案数除以100,000,000的余数。
int main(){
cin >> n >> m;
int t;
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
cin >> t;
map[i] = (map[i] << 1) + t;
}
}
int state = 1 << m;
// 处理状态i是否合法
for (int i = 0; i < state; i++){
if ( ( (i << 1) & i) == 0 && ( ( (i >> 1) & i) == 0 ) )
can[i] = 1;
}
// f[i][j] 表示前i行,且第i行的状态为j的方案数
for (int i = 0; i < state; i++){
if (can[i] && ( i & map[1] ) == i ){
f[1][i] = 1;
}
}
for (int i = 2; i <= n; i++){
for (int j = 0; j < state; j++){
// 如果j是一个合法的状态
if (can[j] && (j & map[i]) == j){
for (int k = 0; k < state; k++){
// 如果上一行的状态j与i不冲突
if ( (k & j) == 0){
f[i][j] = (f[i][j] + f[i - 1][k]) % mod;
}
}
}
}
}
long long ans = 0;
for (int i = 0; i < state; i++)
ans = (ans + f[n][i]) % mod;
cout << ans;
}
标签:lang == ++ main 分配 一个 c++ 输入 状态
原文地址:https://www.cnblogs.com/keik/p/12703557.html