状压dp,调了好久也调不好,希望大佬救救

P2704 [NOI2001] 炮兵阵地

xiuman @ 2024-09-11 22:07:24

#include<bits/stdc++.h>
using namespace std;
int line[105];//每行的山丘与平原 
int state[1024],num[1024];//一行全是平原时可能的状态和炮兵数量 
int dp[3][1050][1050];//滚动数组,此行状态和上一行状态 
int n,m,cnt;//cnt为状态数量 
char x;
void getstate(int now,int ans,int nu){
    if(now>=m){
        state[++cnt]=ans;
        num[cnt]=nu;
        return;
    }
    getstate(now+1,ans,nu);
    getstate(now+3,ans+(1<<now),nu+1);
    return;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){//将每行地形二进制化 
            cin>>x;
            line[i]<<1;
            line[i]+=(x=='H'?1:0);
        }
    }
    getstate(0,0,0);
    for(int i=1;i<=cnt;i++){//对第一行初始化 
        if(line[1]&state[i])continue;
        dp[1][i][0]=num[i];
    }
    for(int i=1;i<=cnt;i++){
        for(int j=1;j<=cnt;j++){//对第二行初始化 
            if(line[2]&state[j])continue;
            if(line[1]&state[i])continue;
            if(state[i]&state[j])continue;
            dp[2][j][i]=max(dp[1][i][0]+num[j],dp[2][j][i]);
        }
    }
    for(int k=3;k<=n;k++){
        for(int i=1;i<=cnt;i++){
            if(line[k-1]&state[i])continue;
            for(int j=1;j<=cnt;j++){
                if(line[k]&state[j])continue;
                if(state[i]&state[j])continue;          
                for(int y=1;y<=cnt;y++){
                    if(line[k-2]&state[y])continue;
                    if(state[y]&state[j])continue;
                    if(state[y]&state[i])continue;
                    dp[k%3][j][i]=max(dp[(k-1)%3][i][y]+num[j],dp[k%3][j][i]);
                }
            }
        }
    }
    int ans=0;
    for(int i=1;i<=cnt;i++){
        for(int j=1;j<=cnt;j++){
            ans=max(ans,dp[n%3][j][i]);
        }
    }
    cout<<ans<<endl;
    return 0;
}

|