标签:状态 玉米田 洛谷 int 状压 st 种地 return false
题目描述
输入描述
输出描述
输入样例
2 3
1 1 1
0 1 0
输出样例
9
互不侵犯 的青春版(?),本题省去了对于数量上限的要求,因此仅需使用二维状态 f [ i ] [ j ] 即可,其中 i 表示种到了第 i 行,j 表示该行是以第 j 种状态种地。
对于每一行,同样进行初始化枚举每一种状态是否符合种地要求,若存在相邻的 1 则将该状态标为非法。
状态转移方程:
f [ i ] [ j ] = f [ i − 1 ] [ x ] f[i][j]=f[i-1][x] f[i][j]=f[i−1][x]
其中 x 表示上一行采用的种地状态。
本题中唯一的特殊点是:某些地可能不允许种。因此对于即将转移到的第 i 行,需要考虑状态 j 是否与这一行的土地状态相匹配,若改行的某个土地为不允许播种,而状态 j 在该土地上种植了作物,则该状态与该行冲突,直接忽略即可。
由于数据范围不是很大,直接在答案处取模即可。
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=15,M=1<<14;
int g[N][N];//存放土地情况
bool st[M];
ll f[N][M];
int mod=1e8;
int n,m;
bool check(int col,int now){
if(!st[now])
return false;
for(int j=1;j<=m;j++){
if((g[col][j]==0)&&(((now>>(m-j))&1)==1))
return false;
}
return true;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>g[i][j];
}
}
//预处理
for(int i=0;i<1<<m;i++){
st[i]=true;
for(int j=0;j<m;j++){
if(((i>>j)&1)&&(i>>(j+1)&1))
st[i]=false;
}
}
f[0][0]=1;
for(int i=1;i<=n+1;i++){
for(int j=0;j<1<<m;j++){
for(int x=0;x<1<<m;x++){
if(!check(i,j))
continue;
if((j&x)!=0)
continue;
f[i][j]=(f[i-1][x]+f[i][j]);
}
}
}
cout<<f[n+1][0]%mod;
return 0;
}
标签:状态,玉米田,洛谷,int,状压,st,种地,return,false 来源: https://blog.csdn.net/laysan/article/details/121308648
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。