• HihoCoder 1634 Puzzle Game


    题目:https://cn.vjudge.net/problem/HihoCoder-1634

    题意:给你一个矩阵,可以修改其中一个值为p,让你求最大子矩阵的最小值

    我们可以暴力枚举每个点是否修改

    当这个点不在最大矩阵内时,一定是它的上下左右的最大子矩阵大

    当这个点在最大矩阵内时,可以直接判断

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    using namespace std;
    const int N=150+5;
    const int inf=0x80808080;
    int L[N],R[N],U[N],D[N];
    int a[N][N],dp[N][N],ma[N][N];
    int n,m,p;
    void init()
    {
        memset(L,0x80,sizeof(L));
        memset(R,0x80,sizeof(R));
        memset(U,0x80,sizeof(U));
        memset(D,0x80,sizeof(D));
    }
    void solve()
    {
        int t;
        //down
        memset(dp,0,sizeof(dp));
        memset(ma,0x80,sizeof(ma));
        t=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;
                    t=max(t,ma[l][r]);
                }
            }
            D[i]=t;
        }
        //up
        memset(dp,0,sizeof(dp));
        memset(ma,0x80,sizeof(ma));
        t=inf;
        for(int i=n;i>=1;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;
                    t=max(t,ma[l][r]);
                }
            }
            U[i]=t;
        }
        //right
        memset(dp,0,sizeof(dp));
        memset(ma,0x80,sizeof(ma));
        t=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;
                    t=max(t,ma[l][r]);
                }
            }
            R[i]=t;
        }
        //left
        memset(dp,0,sizeof(dp));
        memset(ma,0x80,sizeof(ma));
        t=inf;
        for(int i=m;i>=1;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;
                    t=max(t,ma[l][r]);
                }
            }
            L[i]=t;
        }
    }
    int main()
    {
        while(scanf("%d%d%d",&n,&m,&p)!=EOF)
        {
            init();
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    scanf("%d",&a[i][j]);
            solve();
            int ans=D[n];
            /*
                为什么可以枚举所有点
                因为如果这个点不在最大矩阵内,
                当D[n]-a[i][j]+p变大时,不影响ans
                当D[n]-a[i][j]+p变小时,不影响t
            */
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
            {
                int t=max(max(D[i-1],U[i+1]),max(L[j+1],R[j-1]));
                t=max(t,D[n]-a[i][j]+p);
                ans=min(ans,t);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    [HDOJ3523]Image copy detection
    [HDOJ3526]Computer Assembling
    Ubuntu12.04 配置步骤
    const 详解
    ubuntu 12.04 源
    函数参数和数据成员同名
    友元
    静态数据 成员和静态函数
    成员指针
    内存泄露
  • 原文地址:https://www.cnblogs.com/bk-201/p/8728185.html
Copyright © 2020-2023  润新知