炮兵阵地

发现好像只记一行没什么太大的用了。怎么办……

一行不行记两行呗!m=10的情况也只有60种可行方案,空间大大的有。

注意不是累加是取max……

看代码:

#include<bits/stdc++.h>
using namespace std;
int f[105][65][65];
int can[65],num[65],pd[105];
int n,m,bai[13],cnt,ans;
void dfs(int x){
    if(x==m+1){
        cnt++;
        for(int i=1;i<=m;i++)
            can[cnt]=2*can[cnt]+bai[i];
        for(int i=1;i<=m;i++)
            num[cnt]+=bai[i];
        return;
    }
    bai[x]=0;
    dfs(x+1);
    if(bai[x-1]==0&&(x==1||bai[x-2]==0))
        bai[x]=1,dfs(x+1);
}
int main(){
    cin>>n>>m;
    string s;
    for(int i=1;i<=n;i++){
        cin>>s;
        for(int j=1;j<=m;j++)
            pd[i]=2*pd[i]+1-(s[j-1]=='P');
    }
    //for(int i=1;i<=n;i++)
    //    printf("%d
",pd[i]);
    
    dfs(1);
    //printf("%d
",cnt);
    //for(int i=1;i<=cnt;i++)
    //    printf("%d
",can[i]);
    for(int i=1;i<=cnt;i++)
        if(!(pd[1]&can[i]))f[1][i][0]=num[i];
    for(int i=1;i<=cnt;i++)
        if(!(pd[2]&can[i]))
            for(int j=1;j<=cnt;j++)
                if(!(pd[1]&can[j]))
                if(!(can[i]&can[j]))
                    f[2][i][j]=max(f[2][i][j],f[1][j][0]+num[i]);
    for(int i=3;i<=n;i++)
        for(int j=1;j<=cnt;j++)
            if(!(pd[i]&can[j]))
            for(int k=1;k<=cnt;k++)
                if(!(pd[i-1]&can[k]))
                for(int p=1;p<=cnt;p++)
                    if(!(pd[i-2]&can[p]))
                    if(!(can[j]&can[k])&&!(can[k]&can[p])&&!(can[j]&can[p]))
                        f[i][j][k]=max(f[i][j][k],f[i-1][k][p]+num[j]);
    for(int i=1;i<=cnt;i++)
        if(!(pd[n]&can[i]))
        for(int j=1;j<=cnt;j++)
            if(!(pd[n-1]&can[j]))
            if(!(can[i]&can[j]))
                ans=max(ans,f[n][i][j]);
    printf("%d
",ans);                    
    return 0;
} 

深深地感到自己的弱小。

原文地址:https://www.cnblogs.com/syzf2222/p/12425431.html