hdu 2830 Matrix Swapping II (dp+树状数组)

小记:1A! 看到这个求最大矩阵的面积,我就想起了前面的1506,1505,2870了, 感觉方法应该不会差太大, 于是从这个方面入手,最后加了树状数组解决的


思路:此题和1505的差别就在于可以任意交换两列,那么我们就可以看成,当处理某一行,我们处理某一点时,

我们保存这点左边的大于它的高度的个数, 以及右边大于它的高度的个数,个数即列数

我们知道这两个值时,那么从上往下处理行时,我们就可以一点一点的求得其通过交换之后,即将那些大于它的高度的列全部移到一起。所能得到的最大面积,就知道了

然后保存最大的那个值就是answer了

求左边大于它的高度和右边大于它的高度的个数,很容易好想到可以用树状数组解决。 

于是加个树状数组来求取左右值。时间复杂度为O(n*m*logm), 3s内完全没问题



code:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8

const int MAX_ = 1010;
const int N = 1010;
const int INF = 0x7fffffff;

int h[MAX_];
int l[MAX_], r[MAX_];
char str[MAX_][MAX_];

int C[MAX_];

int lowbit(int x){return x&(-x);}

void add(int x,int num){
    while(x < N){
        C[x] += num;
        x += lowbit(x);
    }
}

int sum(int x){
    int cnt = 0;
    while(x){
        cnt += C[x];
        x -= lowbit(x);
    }
    return cnt;
}

int main(){
	int n, m, ans;

	while(~scanf("%d%d", &n, &m)){
	    REP(i, 0, m){
            h[i] = 0;
        }
	    ans = -1;

        REP(j, 0, n){
            scanf("%s", str[j]);
            REP(i, 0, m){
                switch(str[j][i]){
                    case '1': h[i] ++;
                    break;
                    case '0': h[i] = 0;
                    break;
                }
            }
            mst(C, 0);

            REP(i, 0, m){
                add(h[i]+1, 1);
                l[i] = i - sum(h[i]) + 1;
                //printf("%d ", l[i]);
            }
            //printf("\n");

            mst(C, 0);

            for(int i = m-1; i > -1; --i){
                add(h[i]+1, 1);
                r[i] = m - i - sum(h[i] + 1);
                //printf("%d ", r[i]);
            }
            //printf("\n");

            REP(i, 0, m){
                int tmp = h[i] * (r[i] + l[i]);
                ans = max(ans, tmp);
            }

        }
        printf("%d\n", ans);
	}
	return 0;
}


你可能感兴趣的:(hdu 2830 Matrix Swapping II (dp+树状数组))