状压就两个字
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<queue>
#include<cctype>
using namespace std;
void out(int x) { while(x) { cout<<(x&1); x>>=1;} }
bool c=0;
char ch;
int L[62]={},B[62]={},A[102]={};
long long F[2][62][62]={},Ans=0,N,M,Lim;
void pre(int step,int state,int cnt,int cooldown)
{
if(step==M)
{
L[++L[0]]=state;
B[L[0]]=cnt;
return;
}
if(!cooldown)pre(step+1,state|(1<<step),cnt+1,2);
pre(step+1,state,cnt,max(cooldown-1,0));
}
int main()
{
scanf("%d%d",&N,&M); Lim=(1<<M)-1;
pre(0,0,0,0);
for(int i=1;i<=N;++i)
{
for(int j=0;j<M;++j)
{
scanf(" %c",&ch);
if(ch=='H')A[i]|=1<<j;
}
}
for(int i=1;i<=N;++i)
{
c=i&1;
memset(F[c],0,sizeof(F[c]));
for(int j=1;j<=L[0];++j)
{
if(A[i]&L[j])continue;
for(int k=0;k<=L[0];++k)
{
for(int g=0;g<=L[0];++g)
{
if((L[k]&L[g])||(L[j]&L[k])||(L[j]&L[g]))continue;
F[c][j][k]=max(F[c][j][k],F[!c][k][g]+B[j]);
}
}
}
}
for(int i=1;i<=L[0];++i)
{
for(int j=1;j<=L[0];++j)
{
Ans=max(Ans,F[c][i][j]);
}
}
printf("%lld",Ans);
return 0;
}
本文深入探讨了状压DP这一高效算法的核心概念与实现细节,通过具体实例讲解如何运用状压DP解决复杂问题,包括状态定义、转移方程及优化技巧。适合有一定算法基础的读者进一步提升解题能力。

421

被折叠的 条评论
为什么被折叠?



