真心求助状压dp入门题

P2704 [NOI2001] 炮兵阵地

Beyond616 @ 2020-10-28 18:19:52

20分,真心求助

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 13
#define ll long long
ll lowbit(ll x) {return (x&(-x));}
#define empty(a,b) memset(a,b,sizeof(a))
using namespace std;
ll dp[N*N][1<<N],n,m,low[1<<N],ans,run;
ll findlow(ll x) {
    return low[x]!=-1?low[x]:low[x]=findlow(x&(x-1))+1;
}
char s[N*N][N];
bool hf(ll k,ll x) {
//  if (k<=0) return true;
    ll u,j=0;
    if ((x&(x<<1))||(x&(x<<2))) return false;
    while (x) {
        u=lowbit(x);
        while ((1<<j)<u) ++j;
        if (s[k][m-j-1]=='H') return false;
        x-=u;
    }
    return true;
}
int main() {
    memset(low,-1,sizeof(low));
    empty(dp,-1);
    low[0]=0;
    scanf("%lld%lld",&n,&m);
    for (ll i=1; i<=n; ++i) scanf("%s",s[i]);
    for (ll i=0; i<(1<<m); ++i)
        if (hf(1,i))
        {
            dp[1][i]=findlow(i);
        } 
    for (ll p=2; p<=n; ++p)
        for (ll i=0; i<(1<<m); ++i)
            if (hf(p,i)) {// printf("µÚ%lldÐУ¬µÚ%lld״̬ÊǺϷ¨µÄ\n",p,i);
                for (ll j=0; j<(1<<m); ++j)
                    if (hf(p-1,j)&&!(i&j))
                    {
                    //  if (p==15) printf("µÚ%lldÐУ¬µÚ%lld״̬ÊǺϷ¨µÄ\n",p-1,j);
                        if (p!=2)
                            for (ll k=0; k<(1<<m); ++k)
                            {
                                if (hf(p-2,k)&&!((i&j)||(j&k)||(k&i)))
                                    {
                                    //  if (p==15) printf("µÚ%lldÐУ¬µÚ%lld״̬ÊǺϷ¨µÄ\n",p-2,k);
                                        dp[p][i]=max(dp[p][i],dp[p-2][k]+findlow(j)+findlow(i));
                                    //  printf("Run at:%lld\n",++run);
                                    }
                                else;
                            }
                        else dp[p][i]=max(dp[p][i],findlow(i)+findlow(j));
                    }
            }
    for (ll i=0; i<(1<<m); ++i)
        if (hf(n,i)) ans=max(ans,dp[n][i]);
    printf("%lld",ans);
}

by smy2006 @ 2020-10-28 18:43:38

你管这叫入门?


by Semsue @ 2020-10-28 18:49:50

@smy2006 这不是状压入门吗?


by Semsue @ 2020-10-28 18:50:53

hf复杂度太高吧


by nonanalyzer @ 2020-10-28 19:12:28

@滴水穿石 dp数组不能只记一行的状态,会导致上上行的最优解(dp[p-2][k])不一定与上一行兼容。


by ducati @ 2020-12-03 09:17:40

@滴刘天择穿石 您要么用三进制状压二维dp,要么用二进制状压三维dp,您这写的四不像啊……


|