15
#include
#include
#include
#include
#include
using namespace std;
int findmax(int a[],int n)
{
int b = 0,ret=-999;
int i;
for(i = 1;i <= n;i++)
{
if(b > 0)//判断的其实是上一次输入的状态//如果上一次的值是小于零的,那不如舍弃 //就算上一次7+-1小了,但是max还是保留的最大的情况
{
b += a[i];
}
else
{
b = a[i];
}
ret=max(ret,b);
}
return ret;
}
int main()
{
int i,j,k,n,now=0;
int v[105][105];
int ret[100];
int cjc=-999;
while(cin>>n)
{
memset(v,0,sizeof(v));
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
cin>>v[i][j];
}
}
for(i=1;i<=n;i++)//行的起始点
{
memset(ret,0,sizeof(ret));
for(j=i;j<=n;j++)//以i为起始点的行开始,遍历所有可能的矩阵的和
{
for(k=1;k<=n;k++)//列的变化
{
ret[k] += v[j][k];
}
now=findmax(ret,k);
cjc=max(cjc,now);
}
}
cout<
可能还是我见的世面太少了,我觉得这个题也非常的棒啊
暴力,遍历所有的矩形
固定行动列,固定列动行都行,只不过后者难以实现一些,在脑子里难以实化
首先循环起始行标——【1,n】
然后计算以当前行标为首的所有子矩阵的最优max【i,n】
让后循环列~~每一行都要循环列【1,n】
我就问了————那这样没法遍历到列在中间的情况啊,你这列都是从第一列开始的,不慌,计算的时候,处理的非常的精彩,真的让我收益颇多啊~~
以上——就可以遍历所有子矩形了~~
然后开始求单个矩形的和,这单个矩形是指行高为J,列宽固定为1的矩形,这样求最优和的时候,才能方便的得知,最优解是要几列
ret[k] += v[j][k];
注意ret中下标为k
让后开始findmax,b算是上一个单个矩形的最优和,如果它小于零,证明前面矩形求得和加起来是负数,只会,让下面的求和更小,不如舍去前面所有矩形不加,然后,起始点更新为当前单个矩形,如果大于零能,那就继续求和,不管后面单个矩形和为正为负,反正这个过程 的最优解已经被记录最后,返回最优解。
注意清空一下数据,防止对下次造成影响
你可能感兴趣的:(oj)