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;
}