题目链接:https://cn.vjudge.net/problem/HihoCoder-1634
题目意思:可以让矩阵里的某一个数变成p,或者不修改。求最大子矩阵最小,输出最小值。
思路:请看下图
代码:
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
using namespace std;
typedef long long int LL;
int max(int a,int b,int c,int d)
{
return max(max(a,b),max(c,d));
}
const int maxn=155;
const int INF=2e9+1e8;
int n,m,p;
int a[maxn][maxn],dp[maxn][maxn],ma[maxn][maxn],L[maxn],R[maxn],U[maxn],D[maxn];
void init()
{
memset(L, 0x88, sizeof(L));
memset(R, 0x88, sizeof(R));
memset(U, 0x88, sizeof(U));
memset(D, 0x88, sizeof(D));
}
void deal()
{
int tmp;
// xia
memset(dp, 0, sizeof(dp));
memset(ma, 0x88, sizeof(ma));
tmp = -INF;
for (int i = 1; i <= n; i++)
{
for (int l = 1; l <= m; l++)
{
int sum = 0;
for (int r = l; r <= m; r++)
{
sum += a[i][r];
dp[l][r] += sum;
ma[l][r] = max(ma[l][r], dp[l][r]);
if (dp[l][r] < 0)
dp[l][r] = 0;
tmp = max(tmp, ma[l][r]);
}
}
D[i] = tmp;
}
// zuo
memset(dp, 0, sizeof(dp));
memset(ma, 0x88, sizeof(ma));
tmp = -INF;
for (int i = m; i>0; i--)
{
for (int l = 1; l <= n; l++)
{
int sum = 0;
for (int r = l; r <= n; r++)
{
sum += a[r][i];
dp[l][r] += sum;
ma[l][r] = max(ma[l][r], dp[l][r]);
if (dp[l][r] < 0)
dp[l][r] = 0;
tmp = max(tmp, ma[l][r]);
}
}
L[i] = tmp;
}
// shang
memset(dp, 0, sizeof(dp));
memset(ma, 0x88, sizeof(ma));
tmp = -INF;
for (int i = n; i>0; i--)
{
for (int l = 1; l <= m; l++)
{
int sum = 0;
for (int r = l; r <= m; r++)
{
sum += a[i][r];
dp[l][r] += sum;
ma[l][r] = max(ma[l][r], dp[l][r]);
if (dp[l][r] < 0)
dp[l][r] = 0;
tmp = max(tmp, ma[l][r]);
}
}
U[i] = tmp;
}
// you
memset(dp, 0, sizeof(dp));
memset(ma, 0x88, sizeof(ma));
tmp = -INF;
for (int i = 1; i <= m; i++)
{
for (int l = 1; l <= n; l++)
{
int sum = 0;
for (int r = l; r <= n; r++)
{
sum += a[r][i];
dp[l][r] += sum;
ma[l][r] = max(ma[l][r], dp[l][r]);
if (dp[l][r] < 0)
dp[l][r] = 0;
tmp = max(tmp, ma[l][r]);
}
}
R[i] = tmp;
}
}
int main()
{
while(scanf("%d%d%d",&n,&m,&p)+1)
{
init();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
}
deal();
int ans=D[n];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int tmp=max(D[i-1],U[i+1],L[j+1],R[j-1]);
tmp=max(tmp,D[n]-a[i][j]+p);
ans=min(ans,tmp);
}
}
printf("%d
",ans);
}
return 0;
}
/*
3 3 -10
-100 4 4
4 -10 4
4 4 1
3 3 -1
-2 -2 -2
-2 -2 -2
-2 -2 -2
*/