O2已过,求教如何降低时间复杂度

P2704 [NOI2001] 炮兵阵地

lyxleo @ 2022-07-04 14:46:24

#include <bits/stdc++.h>
using namespace std;
int n,m;
int state[101];
long long dp[101][1<<10][1<<10];
inline bool check(int x);
inline int count_num(int x);
inline bool fit(int x,int y){
    return (x & y) == 0;
}
inline bool in(int line,int x){
    return (x & state[line]) == x;
}
int num;
int main(){
    scanf("%d %d",&n,&m);
    for(int i = 1;i <= n;++i){
        for(int j = 0;j < m;++j){
            char c;
            scanf(" %c",&c);
            if(c == 'P'){
                state[i] |= (1 << j);
            }
        }
    }
    state[0] = (1 << 10) - 1;
    for(int i = state[1];i;i = (i - 1) & state[1]){
        if(check(i)){
            num = count_num(i);//Calculate the quantity of 1
            for(int j = 0;j < (1 << m);++j){
                dp[1][i][j] = num;
            }
        }
    }
    for(int line = 2;line <= n;++line){
        for(int i = 0;i < (1 << m);++i){
            if(check(i) && in(line,i)){
                int num = count_num(i);
                for(int j = 0;j < (1 << m);++j){
                    if(check(j) && in(line-1,j) && fit(i,j)){
                        for(int k = 0;k < (1 << m);++k){
                            if(in(line-2,k) && check(k) && fit(j,k) && fit(i,k)){
                                dp[line][i][j] = max(dp[line][i][j],dp[line-1][j][k] + num);
                            } 
                        }
                    }
                }
            }
        }
    }
    long long ans = -1;
    for(int i = 0;i < (1 << m);++i){
        if(check(i) && in(n,i)){
            for(int j = 0;j < (1 << m);++j){
                if(check(j) && in(n-1,j)){
                    ans = max(ans,dp[n][i][j]);
                }
            }
        }
    }
    printf("%lld",ans);
    return 0;
}

inline bool check(int x){//Check for errors in line x
    return (((x >> 1) & x) == 0 && ((x >> 2) & x) == 0);
}

inline int count_num(int x){//ditto
    int cnt = 0;
    while(x){
        if(x & 1){
            ++cnt;
        }
        x >>= 1;
    }
    return cnt;
}

by 拾然z @ 2022-07-04 14:49:47

tlqtj


by Xeqwq @ 2022-07-04 14:57:51

@拾然z ?建议学习什么是时间复杂度。人家求助降复杂度有问题吗


by 拾然z @ 2022-07-04 14:59:00

@整活队长xeq yysy四层循环确实要降,但是鉴于我还没a过这个题……


by lyxleo @ 2022-07-04 15:09:51

@整活队长xeq 大佬有啥好办法吗


by Wch_1910231 @ 2022-07-28 14:46:08

非本质:建议使用快速读入 inline int readd() { char c; bool flag=false; while((c=getchar())>'9'||c<'0') if(c=='-')flag=true; int res=c-'0'; while((c=getchar())>='0'&&c<='9') res=(res<<3)+(res<<1)+c-'0'; return flag? -res : res; } 如输入n即为 int n=readd();


by cyx20080216 @ 2022-08-26 14:33:32

@lyxleo 建议先预处理出每层所有可行的状态,这样每次循环需要枚举的状态数就非常少了,只有60个


|