萌新求助状压dp

P2704 [NOI2001] 炮兵阵地

Vector_Mingfan @ 2021-07-20 11:15:23

#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 201
#define M 505
using namespace std;
int n,m,cnt,dp[N][M][M],num[M],a[N],s[M];
char x;
int DP() {
    int ans=0;
    for(int i=1;i<=cnt;i++) {dp[1][i][1]=num[i]; ans=max(ans,dp[1][i][1]);}
    for(int i=2;i<=n;i++) {
        for(int j=1;j<=cnt;j++) {
            int s1=s[j];
            if((s[j]|a[i])!=a[i]) continue;
            for(int k=1;k<=cnt;k++) {
                int s2=s[k];
                if((s2|a[i-1])!=a[i-1]) continue;
                if(s1&s2) continue;
                for(int y=1;y<=cnt;y++) {
                    int s3=s[y];
                    if((s3|a[i-2])!=a[i-2]) continue;
                    if((s[j]&s[y])||(s[k]&s[y])) continue;
                    dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][y]+num[j]);
                    ans=max(ans,dp[i][j][k]);
                }
            }
        }
    }
    return ans;
}
int main() {
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=m;j++) {
            scanf("%c",&x);
            if(x=='P') a[i]=a[i]|(1<<(m-j));
        }
    }
    for(int i=0;i<(1<<m);i++) {
        if((i&(i<<1))||(i&(i<<2))) continue;
        int k=0;
        for(int j=0;j<m;j++) if(i&(1<<j)) k++;
        cnt++; s[++cnt]=i; num[cnt]=k;
    }
    printf("%d",DP());
    return 0;
}

只A了一个点啊


|