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


    最大子段和(略)

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

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

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

    即dp[i-1]<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
    ",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 
    
  • 相关阅读:
    (转) 理解Angular中的$apply()以及$digest()
    Gulp 有用的地址
    AngularJS中Directive指令系列
    让博客园博客中的图片支持fancybox浏览
    Drupal7 实现like(点赞)功能
    Drupal7 针对特定条件才显示区块
    Windows server 2008 tomcat间歇性掉线关闭
    关于tomcat8在windows2008下高并发下有关问题的解决方案
    combotree 的简单使用2
    @responseBody 返回更多数据
  • 原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11634703.html
Copyright © 2020-2023  润新知