最大子矩阵
【题目描述】
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1×11×1)子矩阵。
比如,如下4×44×4的矩阵
09−4−1−2218−7−6−40021−20−2−7092−62−41−41−180−2
的最大子矩阵是
9−4−121892−41−18
这个子矩阵的大小是1515。
【输入】
输入是一个N×NN×N的矩阵。输入的第一行给出N(0<N≤100)N(0<N≤100)。再后面的若干行中,依次(首先从左到右给出第一行的NN个整数,再从左到右给出第二行的NN个整数……)给出矩阵中的N2N2个整数,整数之间由空白字符分隔(空格或者空行)。已知矩阵中整数的范围都在[−127,127][−127,127]。
【输出】
输出最大子矩阵的大小。
【输入样例】
4 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2
【输出样例】
15
【来源】

分析:其思路就是1就是前缀和概念,上图第二个矩阵就是各行前几列之和。接下贪心策略就是:列是是从j=i+1-n至i=0-n-1。每列都要试过去。
for (i列的起位)
for(j列的终位)
for(行从1到N)
用a[k][j]-a[k][i]再做累加,累加是行与行之间相关求最大值,也就是相当于区域值能否达到最大。
思考:如果我们不是按列求前缀和二维一维化(不一维化,区域探测就要考虑四维,想想是不是。
第二点思考:时间复杂度多少o(n^3)
第三点思考:如果是求列上的求的前缀呢????;>一样的啊,接下来就要列上试来试去了。
第四点思考:贪心策略是什么。预处理前缀和,然后单列或单行上累加试最大值,最大的那个就是结果。
贪心的本质就是局部最优解也就是最终的最优解。
#include<bits/stdc++.h>
using namespace std;
int a[102][102];
int main()
{
int n,ans,max=-999999999;
cin>>n;
for (int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
a[i][j]+=a[i][j-1];
}
// cout<<endl;
// for (int i=1;i<=n;i++)
// { for(int j=1;j<=n;j++)
// { cout<<a[i][j]<<" ";
// }
// cout<<endl;
// }
for (int i=0 ;i<=n-1;++i)
for(int j=i+1;j<=n;++j)
{
ans=0;
for(int k=1;k<=n;++k)
{
ans=ans+(a[k][j]-a[k][i]);
if(ans>max){
max=ans;
// cout<<"k:"<<k<<"j:"<<j<<"i:"<<i<<"ans:"<<ans<<endl;
}
if(ans<0)ans=0;
}
}
cout<<max<<endl;
return 0;
}

浙公网安备 33010602011771号