Niu Ke Xiaobai Yue 23 A (subset generation + subset prefix sum)


Insert picture description here
Idea A :
Because the range of the row is relatively small and the range of the column is relatively large, you can 2 n 2^n pieces are held in the selection method, and then judge whether it is feasible. the complexity THE ( 2 n m ) O(2^n\cdot m)
data is too watery

char w[50][N];
int x[N],y[N];
int _x[N],_y[N];
int main(){
    int t = read();
    while(t--){
        int n = read(),m = read(),a = read(),b = read();
        int S = (1<<n); 
        rep(i,1,n){
            rep(i,1,m){
                w[i][j] = gc();
                if(w[i][j] == '*') x[i] ++,y[j] ++;
            }
        }
        bool r = 1;
        rep(p,0,S-1){
            if(__builtin_popcount(p) != a) continue;
            rep(i,1,n) _x[i] = x[i];rep(i,1,m) _y[i] = y[i];
            rep(i,0,21){
                if((p>>i)&1) {
                    _x[i+1] = 0;
                    rep(j,1,m) if(w[i+1][j] == '*'&&_y[j]) _y[j] --;         
                }
            }
            int cnt = 0;
            rep(i,1,m) if(y[i]) cnt ++;
            if(cnt<=b) {r = 0;break;}
        }
        if(r) puts("yes");
        else puts("no");

    }
}  

THE ( 2 n n + n m ) O(2^n\cdot n + n\cdot m) Practice
Subset prefix and
Because the range of the row is very small, we can compress the enemies in each column into one binary bit m n m\cdot n Pre-process the enemy status of each column and count the number of each status, such as n = 4 n=4 , 1000 represents the status of a certain column, there is an enemy in the fourth row, and c n t [ 1000 ] = 2 cnt[1000]=2 Explain that there are two such columns, so if we eliminate the fourth row, the number of enemies in two columns will become 0 1001 = 3 1001=3 it also as the above example said, no, because 1001 1001 contains 1000 , 0001 1000,0001 these two cases, that is to say c n t [ 1001 ] = c n t [ 1001 ] + c n t [ 1000 ] + c n t [ 0001 ] cnt [1001] = CNT [1001] cnt + [1000] + cnt [0001] . This is the purpose of preprocessing your own prefix sum.
After preprocessing, we traverse i : ( 1 < < n ) 1 i:(1<<n )-1 These states, if i i The number of 1 in is less than or equal to a a and m c n t [ i ] < = b m-cnt[i]<=b shows that this can eliminate all columns.
Great

char w[22][N];
unordered_map<int,int> cnt;
int main(){
    int t = read();
    while(t--){
        cnt.clear();
        int n = read(),m = read(),a = read(),b = read();
        rep(i,1,n){
            rep(j,1,m){
                cin >> w[i][j];
            }
        }
        rep(i,1,m){
            int p = 0;
            rep(j,1,n){
                if(w[j][i] == '*') p|= 1<<(j-1);
            }
            cnt[p] ++;
        }
        for(int i = 1;i <= n;++i){
            for(int j = 0;j < (1<<n);++j)
            if(((j>>(i-1))&1) == 0) cnt[j|(1<<(i-1))] += cnt[j];
        }
        bool r = 1;
        rep(i,0,(1<<n)-1){
            if(__builtin_popcount(i)<=a&&m-cnt[i]<= b) {r = 0;break;}
        }
        if(r == 0) puts("yes");
        else puts("no");
    }
}

Published 636 original articles · praised 38 · 60,000 views +

Guess you like

Origin blog.csdn.net/qq_43408238/article/details/105124753