Puzzle Game HihoCoder - 1634

题目链接: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\n",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


*/
posted @ 2017-11-24 16:22  Code-dream  阅读(607)  评论(0编辑  收藏  举报