UVa 10502 - Counting Rectangles

    xiaoxiao2021-04-19  76

    題目:計算一個01矩陣中有多少個不同的矩形。

    分析:動態規劃(DP)。這個題目中使用了多個不同狀態。

                定義狀態:s(i,j)為矩形ixj中矩形個數,f(i,j)為矩形ixj中包含塊(i,j)的矩形個數;

                轉移方程:s(i,j)= s(i-1,j)+ s(i,j-1)- s(i-1,j-1)+ f(i,j);

                定義狀態:l(i,j)為第i行,第j列的位置前面連續1的個數,即以塊(i,j)結束的最大寬;

                轉移方程:f(i,j)= sum(l(i,j)+ min(l(i,j),l(i-1,j))+ ...);

                                    從下向上統計矩形個數,遇到寬度隨著l變小而縮小;

    說明:最近什麼也沒幹╮(╯▽╰)╭。

    #include <stdio.h> #include <stdlib.h> #include <string.h> char b[111][111]; int l[111][111]; int f[111][111]; int s[111][111]; int main() { int r, c; while (~scanf("%d",&r) && r) { scanf("%d",&c); for (int i = 1; i <= r; ++ i) { scanf("%s",&b[i][1]); } memset(l, 0, sizeof(l)); for (int i = 1; i <= r; ++ i) { for (int j = 1; j <= c; ++ j) { l[i][j] = (b[i][j]=='1' ? l[i][j-1]+1 : 0); } } memset(f, 0, sizeof(f)); for (int i = 1; i <= r; ++ i) { for (int j = 1; j <= c; ++ j) { int min = 100; for (int k = i; k >= 1; -- k) { if (min > l[k][j]) { min = l[k][j]; } f[i][j] += min; } } } memset(s, 0, sizeof(s)); for (int i = 1; i <= r; ++ i) { for (int j = 1; j <= c; ++ j) { s[i][j] = s[i][j-1] + s[i-1][j] - s[i-1][j-1] + f[i][j]; } } printf("%d\n",s[r][c]); } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-675675.html

    最新回复(0)