AcWing 最大的和

AcWing

题目描述

给定一个包含整数的二维矩阵,子矩形是位于整个阵列内的任何大小为1 * 1或更大的连续子阵列。

矩形的总和是该矩形中所有元素的总和。

在这个问题中,具有最大和的子矩形被称为最大子矩形。

例如,下列数组:

0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
其最大子矩形为:

9 2
-4 1
-1 8
它拥有最大和15。

输入格式
输入中将包含一个N*N的整数数组。

第一行只输入一个整数N,表示方形二维数组的大小。

从第二行开始,输入由空格和换行符隔开的N2个整数,它们即为二维数组中的N2个元素,输入顺序从二维数组的第一行开始向下逐行输入,同一行数据从左向右逐个输入。

数组中的数字会保持在[-127,127]的范围内。

输出格式
输出一个整数,代表最大子矩形的总和。

数据范围
1≤N≤100

样例

输入样例:
4  
0 -2 -7 0 9 2 -6 2
-4 1 -4  1 -1

8  0 -2
输出样例:
15

思路

(模拟退火) \(O(玄学)\)

关于模拟退火:在食用更佳

时间复杂度分析:太玄学了无法分析
多试几次应该就A了
xs

Code

#include<bits/stdc++.h>
using namespace std;
int n,arr[110][110];
double T;
double eps=1e-4;
double xs=0.98;
int SA(int x,int y)
{
    T=1000;
    int tx=x,ty=y;
    int ans=-0x7FFFFFFF;
    while(T>eps)
    {
        int X=abs(x+((RAND_MAX-2*rand())%min(tx,15)))%tx+1;
        int Y=abs(y+((RAND_MAX-2*rand())%min(ty,15)))%ty+1;
        int sum=arr[tx][ty]-arr[X-1][ty]-arr[tx][Y-1]+arr[X-1][Y-1];
        long long Delta=(long long)sum-ans;
        if(Delta>0)
        {
            ans=sum;
        }
        else
        {
            if(exp(-Delta)<(RAND_MAX-rand())/T)
            {
                x=X;
                y=Y;
            }
        }
        T*=xs;
    }
    return ans;
}
int main()
{
    srand(time(NULL));srand(rand());srand(rand());
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>arr[i][j];
            arr[i][j]+=arr[i-1][j]+arr[i][j-1]-arr[i-1][j-1];
        }
    }
    int ANS=-0x7FFFFFFF;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            ANS=max(ANS,SA(i,j));
        }
    }
    cout<<ANS;
}

posted @ 2019-07-28 15:17  G_A_TS  阅读(363)  评论(0编辑  收藏  举报