动态规划优化问题-6

例五:矩形问题

​ 在一个n✖️m的黑白相间的矩形中,问有多少个全白色的子矩形(0代表黑色,1代表白)

​ 最暴力的方法就是挨个子矩形都去判断,这样的时间复杂度为O(n2✖️m2),在这里就不说了。

​ 我们可以优化,设dp[i][j]代表以(i, j)为右下角的子矩形的个数,再通过l[i][j]数组记录第i行j列向上有多少个连续的白矩形。这样就可以把题目优化到O(n✖️m^2),伪代码如下:

for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
    	minn = l[i][j];
        for (int k = j; k >= 1; k--) {
            minn = min(minn, l[i][k]);
            if (!minn) break;
            ans += minn;
        }
    }
}

​ 但是如果n和m的取值范围都是1e3怎么办?这时,我们就可以通过转移优化中的单调栈优化来进一步进行优化

​ 我们创建一个单调栈数组sta[i]代表第i行的单调栈。保持单调栈递增,那么就可以将题目优化到O(n✖️m)了,详情请看代码:

#include <stdio.h>
#include <ctype.h>
#include <stack>
#define ll long long
using namespace std;

inline int read() {
    int num=0;
    char ch=0;
    while (!isdigit(ch)) {
        ch = getchar();
    }
    while (isdigit(ch)) {
        num = (num<<3) + (num<<1) + (ch^48);
        ch = getchar();
    }
    return num;
}

struct node {
    int inx, val, sum;
    node(int x, int y, int z) {
        inx = x;
        val = y;
        sum = z;
    }
};

stack<node>que[1005];
int l[1005][1005] = {0};

int main () {
    int n, m, a;
    ll ans = 0;
    n = read();
    m = read();
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            a = read();
            if (a) {
                l[i][j] = l[i - 1][j] + 1;
            }
            while (!que[i].empty()) {
                if (que[i].top().val >= l[i][j]) {
                    que[i].pop();
                } else {
                    break;
                }
            }
            node sta(j, l[i][j], 0);
            if (que[i].empty()) {
                sta.sum = j * l[i][j];
            } else {
                sta.sum = que[i].top().sum + (j - que[i].top().inx) * l[i][j];
            }
            que[i].push(sta);
            ans += sta.sum;
            if (ans >= 100007) {
                ans %= 100007;
            }
        }
    }
    printf("%lld\n", ans);
    return 0;
}

转载请注明出处!!!

如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢

猜你喜欢

转载自blog.csdn.net/Ivan_zcy/article/details/86561874
今日推荐