题目不难,可以练手的板子题(甚至我都怀疑这是不是蓝题。。。。)
又快到看红叶的季节了(●’◡’●)ノ
题目大意:给一个m行n列的图,在这个图中可以种草的以1表示,不能种的用0表示,然后放牛上去吃草,牛吃草的位置上下左右不能有其他的牛,问牛在图中有几种摆法。
(这一看就是炮兵阵地的easy version)
先把整张图转化成二进制数,储存在mp[i]里
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=m;i++){
for(int j=n;j>=1;j--){
mp[i]=mp[i]<<1;
mp[i]+=1-a[i][j];//这里是重点,后面回收伏笔
//cout<<mp[i]<<" ";
}
//cout<<mp[i]<<endl;
}
直接写递推式:dp[i][本行状态]+=dp[i-1][上一行状态]
依旧是先遍历第一行得到状态后递推
for(int i=1;i<=num;i++){
if(tmp[i]&mp[1])continue;
dp[1][i]=1;
}
for(int i=2;i<=m;i++){//行数
for(int j=1;j<=num;j++){//状态
if(tmp[j]&mp[i])continue;//回收伏笔,地形不冲突
for(int p1=1;p1<=num;p1++){//上一行的状态
if(tmp[p1]&tmp[j])continue;
else dp[i][j]+=dp[i-1][p1];
}
}
}
最后遍历一遍最后一行的各种状态就可以了
给出ac代码:
#include<bits/stdc++.h>
using namespace std;
const long long pp=1e8;
int a[105][105],s[10005];
long long tmp[10005],mp[105];
long long dp[16][10005];
//int ghs(long long a){
// int ss=0;
// while(a){
// if(a&1)ss++;
// a>>1;
// }
// return ss;
//}
int main(){
int n,m;
cin>>m>>n;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=m;i++){
for(int j=n;j>=1;j--){
mp[i]=mp[i]<<1;
mp[i]+=1-a[i][j];
//cout<<mp[i]<<" ";
}
//cout<<mp[i]<<endl;
}
int num=0;
tmp[++num]=0;
for(long long i=1;i<(1<<n);i++){
if((i&(i<<1))||(i&(i>>1)))continue;
tmp[++num]=i;
//s[num]=ghs(i);
}
for(int i=1;i<=num;i++){
if(tmp[i]&mp[1])continue;
dp[1][i]=1;
}
for(int i=2;i<=m;i++){
for(int j=1;j<=num;j++){
if(tmp[j]&mp[i])continue;
for(int p1=1;p1<=num;p1++){
if(tmp[p1]&tmp[j])continue;
else dp[i][j]+=dp[i-1][p1];
}
}
}
long long ans=0;
for(int i=1;i<=num;i++){
ans+=dp[m][i];
}
ans=ans%pp;
cout<<ans;
}
建议ac了去试试炮兵阵地(老毒瘤题)