90分 WA #9求助

P2704 [NOI2001] 炮兵阵地

zhong0204 @ 2021-02-22 23:10:16

P2704 [NOI2001] 炮兵阵地

#include <iostream>
#include <cstring>
using namespace std;

int n,m,cnt[1<<12],num[1<<12],s[110][1<<12],f[110][110][110];
char c[110][12];

void init(){
    for(int i=0;i<(1<<m);i++){
        if(i&(i<<1)||i&(i<<2)||i&(i>>1)||i&(i>>2))continue;
        for(int j=1;j<=n;j++){
            int sum=0,flag=0;
            for(int k=0;k<m;k++){
                if(i&(1<<k)){
                    if(c[j][m-k]=='H'){
                        flag=1;
                        break;
                    }
                    sum++;
                }
            }
            if(flag)continue;
            s[j][++cnt[j]]=i;
            num[i]=sum;
        }
    }
    return ;
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>c[i][j];
    init();
/*  memset(f,-127,sizeof(f));
    for(int i=0;i<=(1<<11);i++){
        for(int j=0;j<=(j<<11);j++){
            f[0][i][j]=0;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=cnt[i];j++){
            cout<<num[s[i][j]]<<" ";
        }
        cout<<endl;
    }*/
    for(int i=1;i<=cnt[1];i++)  //处理第一排
            f[1][i][0]=num[s[1][i]];
    for(int i=1;i<=cnt[1];i++){ //第二排
        for(int j=1;j<=cnt[2];j++){
            if(!(s[1][i]&s[2][j])){ //判断是否冲突
                f[2][i][j]=num[s[1][i]]+num[s[2][j]];
            } 
        }
    }
    for(int i=3;i<=n;i++){//枚举行 
        for(int j=1;j<=cnt[i];j++){//枚举第i行状态 
            for(int k=1;k<=cnt[i-1];k++){//枚举第i-1行状态 
                if(!(s[i][j]&s[i-1][k]))
                for(int l=1;l<=cnt[i-2];l++){//枚举第i-2行状态
                    if(!(s[i][j]&s[i-2][l])&&!(s[i-1][k]&s[i-2][l]))
                    f[i][j][k]=max(f[i][j][k],f[i-1][k][l]+num[s[i][j]]);
                    //cout<<"i: "<<i<<"  j: "<<j<<"  k: "<<k<<"  l: "<<l<<" -> "<<f[i][j][k]<<endl;
                }
            }
        }
    }
/*  for(int i=1;i<=n;i++)
        cout<<cnt[i]<<" ";
    cout<<endl;*/
/*  for(int i=1;i<=n;i++){
        for(int j=1;j<=cnt[i];j++){
            cout<<s[i][j]<<" ";
        }
        cout<<endl;
    }*/

    int ans=-1e9;
    for(int i=1;i<=cnt[n];i++){
        for(int j=1;j<=cnt[n-1];j++){
            ans=max(ans,f[n][i][j]);
        }
    }
    cout<<ans<<endl;
    return 0;
}

by pymysql @ 2021-08-15 18:32:30

处理第二排的时候,i,j 所对应的状态写反了,修改如下:

for(int i=1;i<=cnt[2];i++){ //第二排
        for(int j=1;j<=cnt[1];j++){
            if(!(s[2][i]&s[1][j])){ //判断是否冲突
                f[2][i][j]=num[s[2][i]]+num[s[1][j]];
            } 
        }
    }

|