题目1102:最小面积子矩阵

来源:互联网 发布:米5登不了淘宝手机助手 编辑:程序博客网 时间:2024/06/06 02:29

java实现:

/********* * 矩阵求和 * sum[i][j] = sum[i - 1][j] + sum[i][j - 1] + maze[i][j]; * 状态转移方程: * dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) * 同时再求以(i,j)为矩阵右下角情况下的最小值 */import java.io.IOException;import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.FileReader;import java.util.Scanner;class Main{public static final boolean DEBUG = false;public static final int N = 110;public static void main(String[] args) throws IOException{Scanner cin;int n, m, k;int min;if (DEBUG) {cin = new Scanner(new FileReader("d:\\OJ\\uva_in.txt"));} else {cin = new Scanner(new InputStreamReader(System.in));}int[][] maze = new int[N][N];int[][] sum = new int[N][N];int[][] dp = new int[N][N];while (cin.hasNext()) {n = cin.nextInt();m = cin.nextInt();k = cin.nextInt();for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {maze[i][j] = cin.nextInt();}}for (int i = 0; i <= n; i++) {sum[i][0] = 0;dp[i][0] = -1;maze[i][0] = 0;}for (int i = 0; i <= m; i++) {sum[0][i] = 0;maze[0][i] = 0;dp[0][i] = -1;}for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + maze[i][j];}}for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (-1 == dp[i - 1][j] && -1 == dp[i][j - 1]) {if (sum[i][j] < k) dp[i][j] = -1;else {min = i * j;for (int x = 1; x <= i; x++) {for (int y = 1; y <= j; y++) {if (sum[i][j] - sum[x - 1][j] - sum[i][y - 1] + sum[x - 1][y - 1] >= k && (i - x + 1) * (j - y + 1) < min)min = (i - x + 1) * (j - y + 1);}}dp[i][j] = min;}} else {if (dp[i - 1][j] > 0 && dp[i][j - 1] == -1) dp[i][j] = dp[i - 1][j];else if (dp[i - 1][j] == -1 && dp[i][j - 1] > 0) dp[i][j] = dp[i][j - 1];else dp[i][j] = (dp[i - 1][j] > dp[i][j - 1] ? dp[i][j - 1] : dp[i - 1][j]);min = dp[i][j];for (int x = i; i - x + 1 < dp[i][j] && x >= 1; x--) {for (int y = j; j - y + 1 <= dp[i][j] / (i - x + 1) && y >= 1; y--) {if (sum[i][j] - sum[x - 1][j] - sum[i][y - 1] + sum[x - 1][y - 1] >= k && (i - x + 1) * (j - y + 1) < min) min = (i - x + 1) * (j - y + 1);}}dp[i][j] = min;}}}System.out.println(dp[n][m]);}}}

C++实现:

#include <cstdio>using namespace std;const int N = 110;int maze[N][N], sum[N][N], dp[N][N];int main(){    int m, n, k;    int i, j, x, y;    int Min;    #ifndef ONLINE_JUDGE        freopen("d:\\OJ\\uva_in.txt", "r", stdin);    #endif // ONLINE_JUDGE    while (scanf("%d%d%d", &n, &m, &k) != EOF) {        for (int i = 1; i <= n; i++) {            for (int j = 1; j <= m; j++) {                scanf("%d", &maze[i][j]);            }        }        for (int i = 0; i <= n; i++) {            maze[i][0] = 0;            sum[i][0] = 0;            dp[i][0] = -1;        }        for (int i = 0; i <= m; i++) {            maze[0][i] = 0;            sum[0][i] = 0;            dp[0][i] = -1;        }        for (int i = 1; i <= n; i++) {            for (int j = 1; j <= m; j++) {                sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + maze[i][j];            }        }        for (int i = 1; i <= n; i++) {            for (int j = 1; j <= m; j++) {                if (-1 == dp[i - 1][j] && -1 == dp[i][j - 1]) {                    if (sum[i][j] < k) dp[i][j] = -1;                    else {                        Min = i * j;                        for (x = 1; x <= i; x++) {                            for (y = 1; y <= j; y++) {                                if (sum[i][j] - sum[x - 1][j] - sum[i][y - 1] + sum[x - 1][y - 1] >= k &&                                    (i - x + 1) * (j - y + 1) < Min) Min = (i - x + 1) * (j - y + 1);                            }                        }                        dp[i][j] = Min;                    }                } else {                    if (dp[i - 1][j] > 0 && dp[i][j - 1] == -1) dp[i][j] = dp[i - 1][j];                    else if (dp[i - 1][j] == -1 && dp[i][j - 1] > 0) dp[i][j] = dp[i][j - 1];                    else dp[i][j] = (dp[i - 1][j] > dp[i][j - 1] ? dp[i][j - 1] : dp[i - 1][j]);                    Min = dp[i][j];                    for (x = i; i - x + 1 < dp[i][j] && x >= 1; x--) {                        for (y = j; j - y + 1 <= dp[i][j] / (i - x + 1) && y >= 1; y--) {                            if (sum[i][j] - sum[x - 1][j] - sum[i][y - 1] + sum[x - 1][y - 1] >= k && (i - x + 1) * (j - y + 1) < Min)                                Min = (i - x + 1) * (j - y + 1);                        }                    }                    dp[i][j] = Min;                }            }        }        printf("%d\n", dp[n][m]);    }    return 0;}


0 0