空间爆炸诚恳求助

P2704 [NOI2001] 炮兵阵地

pengyule @ 2020-10-07 13:45:30

大家好,做这道题时有几个点MLE了,对比题解,发现也并不大啊!十分无助,前来求助。

题目:P2704炮兵阵地

代码:

#include <bits/stdc++.h>
using namespace std;
int a[101],b[1001],cnt[1001];
int ans,dp[101][1001][1001];
    int n,m,tmp,tot,num=1;
    int i,j,s,u,v,w;
    char ch;
int main()
{
    scanf("%d %d",&n,&m);
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++){
            cin>>ch;
            if(ch=='H') a[i]+=(1<<j-1);
        }
    for(s=0;s<(1<<m);s++){
        tmp=s,tot=0;
        while(tmp){
            if(tmp&1) tot++;
            tmp>>=1;
        }
        if((((s>>1)|(s>>2)|(s<<1)|(s<<2))&s)==0){
            b[++num]=s,cnt[num]=tot;
            if((s&a[1])==0) dp[1][0][num]=cnt[num]; 
        }
    }
    for(i=1;i<=num;i++)
        for(j=1;j<=num;j++)
            if(((b[i]&a[2])|(b[i]&b[j])|(b[j]&a[1]))==0)
                dp[2][j][i]=max(dp[2][j][i],dp[1][0][j]+cnt[i]);
    for(i=3;i<=n;i++){
        for(u=1;u<=num;u++){
            if(a[i]&b[u]) continue;
            for(v=1;v<=num;v++)
                for(w=1;w<=num;w++)
                    if(((b[u]&b[v])|(b[u]&b[w])|(b[v]&b[w]))==0)
                        dp[i][v][u]=max(dp[i][v][u],dp[i-1][w][v]+cnt[u]);
        }
    }
    for(i=1;i<=num;i++)
        for(j=1;j<=num;j++)
            ans=max(ans,dp[n][j][i]);
    cout<<ans<<endl;
    return 0;
}

感谢大家付出宝贵时间!


by sheeplittlecloud @ 2020-10-07 13:46:44

@pengyule 数组不要开那么大


by hanzhongtlx @ 2020-10-07 13:49:34

@pengyule 这个数组不滚动过不了


by pengyule @ 2020-10-07 13:51:13

@hanzhongtlx 哦,谢谢,改成了滚动,过了


by pengyule @ 2020-10-07 13:51:48

奇怪,怎么有些题解没有滚动……不会没过吧。。


by momentous @ 2020-10-07 13:53:11

不滚动可以过的


by momentous @ 2020-10-07 13:53:49

每一行的合法状态其实只有一点点


by 幻影星坚强 @ 2020-10-07 13:55:57

你谷评测很玄学貌似是看用了多少的()


|