lyxleo @ 2022-07-04 14:46:24
#include <bits/stdc++.h>
using namespace std;
int n,m;
int state[101];
long long dp[101][1<<10][1<<10];
inline bool check(int x);
inline int count_num(int x);
inline bool fit(int x,int y){
return (x & y) == 0;
}
inline bool in(int line,int x){
return (x & state[line]) == x;
}
int num;
int main(){
scanf("%d %d",&n,&m);
for(int i = 1;i <= n;++i){
for(int j = 0;j < m;++j){
char c;
scanf(" %c",&c);
if(c == 'P'){
state[i] |= (1 << j);
}
}
}
state[0] = (1 << 10) - 1;
for(int i = state[1];i;i = (i - 1) & state[1]){
if(check(i)){
num = count_num(i);//Calculate the quantity of 1
for(int j = 0;j < (1 << m);++j){
dp[1][i][j] = num;
}
}
}
for(int line = 2;line <= n;++line){
for(int i = 0;i < (1 << m);++i){
if(check(i) && in(line,i)){
int num = count_num(i);
for(int j = 0;j < (1 << m);++j){
if(check(j) && in(line-1,j) && fit(i,j)){
for(int k = 0;k < (1 << m);++k){
if(in(line-2,k) && check(k) && fit(j,k) && fit(i,k)){
dp[line][i][j] = max(dp[line][i][j],dp[line-1][j][k] + num);
}
}
}
}
}
}
}
long long ans = -1;
for(int i = 0;i < (1 << m);++i){
if(check(i) && in(n,i)){
for(int j = 0;j < (1 << m);++j){
if(check(j) && in(n-1,j)){
ans = max(ans,dp[n][i][j]);
}
}
}
}
printf("%lld",ans);
return 0;
}
inline bool check(int x){//Check for errors in line x
return (((x >> 1) & x) == 0 && ((x >> 2) & x) == 0);
}
inline int count_num(int x){//ditto
int cnt = 0;
while(x){
if(x & 1){
++cnt;
}
x >>= 1;
}
return cnt;
}
by 拾然z @ 2022-07-04 14:49:47
tlqtj
by Xeqwq @ 2022-07-04 14:57:51
@拾然z ?建议学习什么是时间复杂度。人家求助降复杂度有问题吗
by 拾然z @ 2022-07-04 14:59:00
@整活队长xeq yysy四层循环确实要降,但是鉴于我还没a过这个题……
by lyxleo @ 2022-07-04 15:09:51
@整活队长xeq 大佬有啥好办法吗
by Wch_1910231 @ 2022-07-28 14:46:08
非本质:建议使用快速读入 inline int readd() { char c; bool flag=false; while((c=getchar())>'9'||c<'0') if(c=='-')flag=true; int res=c-'0'; while((c=getchar())>='0'&&c<='9') res=(res<<3)+(res<<1)+c-'0'; return flag? -res : res; } 如输入n即为 int n=readd();
by cyx20080216 @ 2022-08-26 14:33:32
@lyxleo 建议先预处理出每层所有可行的状态,这样每次循环需要枚举的状态数就非常少了,只有60个