标签:div 转化 color namespace ace new 转移 最大 依次
题目来源:http://noi.openjudge.cn/ch0206/1768/
总时间限制: 1000ms;内存限制: 65536kB
铺垫:先想如何找一行一维数组的最大连续元素和呢?
重点是这个状态转移方程: b[i] = max { b[i-1] + b[i] , b[i] };
若到前一个元素为止的“最优的”累加和为正,则计算到当前元素的累加和时,需要加上先前的部分;反之则不。
现在我们来想怎么把二维压缩到一维:
矩阵内的元素为左上角的坐标(x1,y1)和右下角的坐标(x2,y2)决定。
如果我们暂时定下来目前是找 x1,x2 之间的,垂直长度已为|x2-x1|的矩形的最大面积;
那么既然宽度|x2-x1| 已经定下来了,那么这边枚举出来的矩阵面积,必定是某几连续列的整列和。
把每列的元素和都加起来,a[ym,x1]+……a[ym,x2],即得到了一个一维数组。
再按照前面的铺垫,找到最大最大字段和,即为在|x2-x1|宽度约束下的最大矩形
外面再套两层for循环来枚举不同的 x1,x2 即可
以下是AC代码:
1 #include <iostream> 2 #include <cmath> 3 using namespace std; 4 5 int a[105][105]; 6 int b[105]; //算出目前x1-x2行的二维压缩成的一维数组 7 8 int main(){ 9 int N; 10 cin>>N; 11 for(int i=0;i<N;i++){ 12 for(int j=0;j<N;j++){ 13 cin>>a[i][j]; 14 } 15 } 16 int ans=0; 17 for(int i=0;i<N;i++){ 18 for(int j=i;j<N;j++){ 19 memset(b,0,sizeof(b)); 20 for(int p=0;p<N;p++){ 21 for(int q=i;q<=j;q++){ 22 b[p]+=a[q][p];//得到压缩后的一维数组 23 } 24 } 25 for(int k=0;k<N;k++){ 26 b[k]=max(b[k],b[k]+b[k-1]); 27 } 28 for(int k=0;k<N;k++){ 29 ans=max(ans,b[k]); 30 } 31 } 32 } 33 34 cout<<ans<<endl; 35 36 return 0; 37 }
参考博客:https://www.cnblogs.com/GodA/p/5237061.html
标签:div 转化 color namespace ace new 转移 最大 依次
原文地址:https://www.cnblogs.com/Accepted20191024/p/11745232.html