题目描述
给定一个包含整数的二维矩阵,子矩形是位于整个阵列内的任何大小为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了
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;
}
TQL%%%