analysis
首先这是一道状压DP,其次就是方程的设计
设是当前行状态为k,前一行为j,前两行为i??这是我最初的想法,但是没有带入列这个参数,且空间开销为,所以不行
设为第i行状态为K,前一行状态为S,这样的话
这时虽然方程写出来了,但是很多oler都会为其正确性而担忧
对于这个问题,我想引用Q大佬的一句话:
于是就开心的递推了
注意不要把条件写漏了,这把我卡了一下午
code
#include<bits/stdc++.h>
using namespace std;
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define ll long long
int n,m;
const int maxn=110;
const int maxm=10;
const int maxsit=(1<<maxm);
int MAP[maxn];
int sit[maxsit];
int num[maxsit];
int cnt=0;
int f[3][maxsit][maxsit];
template <typename T> void read(T &x)
{
x=0;char r=getchar();T neg=1;
while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
while(r>='0'&&r<='9'){x=(x<<3)+(x<<1)+r-'0';r=getchar();}
x*=neg;
}
inline int getnum(int i){register int _cnt=0;register int _i=i;while(_i){if((_i&1)==1)++_cnt;_i>>=1;}return _cnt;}
inline void makesit()
{
loop(i,0,((1<<(m))-1))
{
if(((i<<1)&i)==0&&((i<<2)&i)==0)
{
sit[cnt]=i;
num[cnt++]=getnum(i);
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("datain.txt","r",stdin);
#endif
read(n);read(m);
clean(f,0);
char ra[maxm];
loop(i,1,n)
{
scanf("%s",ra);
int _aa=0;
loop(j,0,(m-1))
{
_aa<<=1;
if(ra[j]=='H')_aa+=1;
}
MAP[i]=_aa;
}//将地图压成数便于后面判断
makesit();//得到所有合法状态,存在sit和num数组中
loop(K,0,(cnt-1))
{
loop(S,0,(cnt-1))
{
f[1][sit[S]][sit[K]]=num[K];
if((sit[S]&sit[K])==0)
f[2][sit[S]][sit[K]]=num[K]+num[S];
}
}
loop(i,3,n)
{
loop(S,0,(cnt-1))
{
if((sit[S]&MAP[i-1])!=0)continue;//if on the hill
loop(K,0,(cnt-1))
{
if((sit[K]&sit[S])!=0||(sit[K]&MAP[i])!=0)continue;//if can attacked or on the hill
loop(L,0,(cnt-1))
{
if((sit[L]&MAP[i-2])!=0||(sit[L]&sit[S])!=0||(sit[L]&sit[K])!=0)continue;//if L can attack S or K or on the hill
f[i%3][sit[S]][sit[K]]=max(f[(i-1)%3][sit[L]][sit[S]]+num[K],f[i%3][sit[S]][sit[K]]);
}
}
}
}
int res=0;
loop(i,0,(cnt-1))
{
loop(j,0,(cnt-1))
{
if((sit[i]&sit[j])!=0)continue;
res=max(res,f[n%3][sit[i]][sit[j]]);
}
}
printf("%d",res);
return 0;
}