最大子段和||最大子矩阵和||最大全0子矩阵||最大全0子正方形

最大子段和(略)

定义一个最大值dp[i]表示以i结尾的最大子段和;

初始化:
dp[0]=A[0];

dp[i]=max(dp[i-1]+A[i],A[i])

即dp[i-1]+A[i]<0时
dp[i] = A[i];
否则
dp[i]=dp[i-1]+A[i]


最大全0子矩阵

https://blog.csdn.net/Flere825/article/details/54605662

1159 最大全0子矩阵

/*
#define N 2010
int a[N][N],ans,n;
int h[N],l[N],r[N];

#undef int
int main(){
#define int long long
    rd(n);
    rep(i,1,n)
        rep(j,1,n)
            rd(a[i][j]);
    rep(i,1,n){
        rep(j,1,n){
            if(a[i][j])h[j]=0;
            else h[j]++;
        }
        rep(j,1,n){
            l[j]=j;
            while(l[j]>1 && h[j]<=h[l[j]-1])
                l[j]=l[l[j]-1];
        }
        dwn(j,n,1){
            r[j]=j;
            while(r[j]<n && h[j]<=h[r[j]+1])
                r[j]=r[r[j]+1];
        }
        rep(j,1,n)
            ans=max(ans,h[j]*(r[j]-l[j]+1));
    }
    printf("%lld",ans);
    return 0;
}

最大子矩阵的和

/*
reference:

translation:

solution:
    思路:我们知道一种求最大子段和的方法(什么你不知道?),就是O(n)遍历这个一维的数组,把当前遍历的数加入一个变量(tmp),在这个过程中记录最大值,如果这个变量变成负数,
那么就把这个变量置零,继续往下遍历。
为什么呢?
如果我们加入的这个数是一个正数,那正和我们意(我们意是什么鬼),因为正数可以让变量(tmp)更大,我们需要的就是一个最大值,如果加入的数是一个负数的话,分两种情况
1、tmp >= 0
        这样的话对于后面加入的数来说,我们前面所加的数是有意义的,因为变量还是一个正数(虽然减小了),它仍可以使得后面加入的数变大(哲学的声音?)
2、tmp < 0
        这样对于后面加入的数来说,我们前面所加的数毫无意义,它使得后面的数反而更小了,所以我们就不要前面的数了(一脸嫌弃),将tmp置零。

那么给你一个二维数组,求一个最大的子矩阵,和这个有什么关系呢? 一维数组 == n*1*1的二维矩阵
这么一看我们好像已经完成了对于一个特殊二维矩阵求最大子矩阵和。

那么对于题目给出的二维矩阵,我们可以转换为我们的特殊矩阵。我们枚举i、j,表示将i~j行看成一维数组,我们将a[i][k]+=a[j][k](对应位置相加),对a[i]这个一维数组求最大字段和
trigger:

note:
    *
record:

date:
    2019.08.20
*/
int a[505][505];
int dp[510][510];

int n;
int main(){
    while(~scanf("%d",&n)){
        rep(i,1,n)
            rep(j,1,n)
                rd(a[i][j]);
        memset(dp,0,sizeof(dp));
        rep(i,1,n)
            rep(j,1,n)
                dp[i][j]=dp[i-1][j]+a[i][j];
        rep(i,1,n){
            rep(j,1,n)
                printf("%d ",dp[i][j]);
            puts("");
        }
        int sum=0,ans=-0x3f3f3f3f;
        dwn(i,n,1){
            rep(j,1,i-1){
                sum=0;
                rep(k,1,n){
                    sum+=dp[i][k]-dp[j][k];
                    if(sum>ans)
                        ans=sum;
                    if(sum<0)
                        sum=0;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
/*
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
*/
//15

最大全0子正方形(的面积)

/*
reference:

translation:

solution:
    DP的思路,我们假设f(i,j)表示的是以i,j为右下角顶点的最大子正方形的边长。
这样初始条件f(1,j) f(i,1)即第一行和第一列分别都是自己的值的相反数(因为是0的子矩阵而不是1 啦) 

如果a(i,j)为1,
    更新f[i][j]=0(说明以ij为右下角顶点的最大子正方形的边长为0),
如果f(i,j)==1,
    f(i,j)更新为min(f(i-1,j),f(i,j-1),f(i-1,j-1))+1
trigger:

note:
    *
record:

date:
    2019.09.03
*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dwn(i,a,b) for(int i=a;i>=b;--i)
template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;}
inline void write(int n){if(n==0)return;write(n/10);putchar(n%10+'0');}
#define mem(a,b) memset(a,b,sizeof(a))
#define ee(i,u) for(int i=head[u];i;i=e[i].next)

#define N 1010

int n,maxx;
int a[N][N],f[N][N];

#undef int
int main(){
#define int long long
    #ifdef WIN32
    freopen("max_juzhen.txt","r",stdin);
    #endif
    rd(n);
    rep(i,1,n)
        rep(j,1,n){
            rd(a[i][j]);
        }
    rep(i,1,n)f[i][1]=-a[i][1];
    rep(i,1,n)f[1][i]=-a[1][i];
    rep(i,1,n){
        rep(j,1,n){
            if(a[i][j])f[i][j]=0;
            else {
                f[i][j]=min(f[i-1][j-1],min(f[i-1][j],f[i][j-1]))+1;
                maxx=max(maxx,f[i][j]);
            }
        }
    }
    printf("%lld",maxx*maxx);
    return 0;
}
/*
5
0 1 0 1 0
0 0 0 0 0
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0
*/
//9 

原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11634703.html

时间: 2024-11-06 07:43:30

最大子段和||最大子矩阵和||最大全0子矩阵||最大全0子正方形的相关文章

Codevs 1159 最大全0子矩阵 悬线法!!!!

1159 最大全0子矩阵 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O的个数最多. 输入描述 Input Description 输入文件第一行为整数N,其中1<=N<=2000,为方阵的大小,紧接着N行每行均有N个0或1,相邻两数间严格用一个空格隔开. 输出描述 Output Description 输出文件仅一行包含一个整数表示要求的最大的全零子矩阵中零的个数.

最大全1子矩阵

http://blog.csdn.net/zhang20072844/article/details/12925581 给出1个M*N的矩阵M1,里面的元素只有0或1,找出M1的一个子矩阵M2,M2中的元素只有1,并且M2的面积是最大的.输出M2的面积. Input 第1行:2个数m,n中间用空格分隔(2 <= m,n <= 100) 第2 - N + 1行:每行m个数,中间用空格分隔,均为0或1. Output 输出最大全是1的子矩阵的面积. Input 示例 3 3 1 1 0 1 1 1

1159 最大全0子矩阵

/*f(i,j)表示以(i,j)为右下角的最大全0子矩阵的边长若a[i][j]==1,f(i,j)=0否则:f(i,j)=min{ f(i-1,j),f(i,j-1),f(i-1,j-1) }+1 这样求得的是最大全0正方形子矩阵要求长方形矩阵,上述思路行不通假设以(i,j)为右下角的最大矩阵=12它可能是3*4.4*3.2*6.6*2.1*12.12*1按上述思路进行状态转移的话,取得最优值的方案不唯一时,所有的方案需要都记下,用于后续的状态转移. 在长方形全0子矩阵中,考察某个位置(i,j)

CODEVS1159 最大全0子矩阵

题目描述 Description 在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O的个数最多. 思路:这个题最朴素的n^6的算法,超时美美的...然后想优化,从一个点向上方.左方.右方扩展,首先更新这个点向上能有多少个0h0,然后找左右h比h0大的作为左右边界,然后计算这个矩形的面积,最后输出最大值...这种构造的美丽算法,真心... 比较: 最大全0子正方形:f[i][j](以i,j为右下角的最大正方形的边长)=min(f[i-1][j],f[i][j-1],f[i-1][j-1])

Android5.0开发范例大全 读书笔记(六)

(六)与系统交互 6.1后台通知 1.关于后台通知,下面展示6种样式.值得一提的是,笔者的小米5只能显示基本样式,雷军真是良心厂商啊. 2.首先上布局xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="

cmd命令大全/cmd命令提示符大全

刚接触电脑的时候是从DOS系统开始,DOS时代根本就没有Windows这样的视窗操作界面,只有一个黑漆漆的窗口,让你输入命令.所以学DOS系统操作,cmd命令提示符是不可或缺的.可以告诉大家,大多数的程序员牛人或计算机专家在DOS系统下的操作是非常了得的,所以菜鸟要想成为计算机高手,DOS命令是非学不可. 直到今天的Windows系统,还是离不开DOS命令的操作.学习DOS系统操作,首先了解命令提示符.先了解每个命令提示符的作用,然后才能够灵活运用. 下面将详细的为大家介绍cmd命令大全的符号和

Substance风格实例大全javaswing皮肤风格大全(原)

转载请注明来路:http://www.cnblogs.com/langtianya/ 下图是所支持的设置 下面把上面的每一个选项的子选项进行试验 substance皮肤: AutumnSkin BusinessSkin BusinessBlackSteelSkin BusinessBlueSteelSkin ChallengerDeepSkin CremeSkin EmeraldDuskSkin FieldOfWheatSkin FindingNemoSkin GreenMagicSkin Ma

UltraEdit快捷键大全 UltraEdit常用快捷键大全

UltraEdit是一套功能强大的文本编辑器,可以编辑文本.十六进制.ASCII码,可以取代记事本,内建英文单字检查.C++及VB指令突显,可同时编辑多个文件,而且即使开启很大的文件速度也不会慢. 说到编辑器的快捷键,VIM是无与伦比的.要反对,也得是带脚踏板的EmaCS.UE还是有差距的,很大差距.注意:VIM是开源.免费的,而UE则需要注册.UE是Windows下最好的编辑器--如果没有GVIM和Emacs的话.而VIM和Emacs则是任何操作系统下最好的编辑器. 自定义快捷键:UE很多功能

Leetcode:Maximal Rectangle 最大全1子矩阵

Maximal Rectangle Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area. 解题分析: 联想到 最大矩形面积 这一题,可以在O(n)时间内求出 最大的矩形面积 如果我们把每一行看成x坐标,那高度就是从那一行开始往上数的1的个数. 利用 最大矩形面积 的方法,在O(n2)时间内就可以求出每一行形成的“柱状