• 最大矩形土地 单调栈或者DP


    问题:
    有一天,小猫(rainbow)(freda)来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。
    这片土地被分成(N imes M) 个格子,每个格子里写着(’R’)或者(’F’)(R)代表这块土地被赐予了(rainbow)(F)代表这块土地被赐予了(freda)
    现在(freda)要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着(’F’)并且面积最大。
    它们决定,如果你找到的土地面积为(S),它们给你(3 imes S)两银子。

    解:
    这题有多种做法 双端队列的解法我就不说了

    这里介绍单调栈和DP 的方法

    1.单调栈
    首先我们先注意到对于一个合法的序列 答案一定是长度 $ imes min(H) $
    并且对于一个单调的栈 从左到右每个元素都能够和右边的配成对 并且高度为当前元素的H
    考虑当栈顶元素的H>枚举到的H
    那么就不满足单调性 所以我们需要进行强制单调 好让成为一个单调的序列
    最后考虑再次统计答案即可
    code:

    #include<bits/stdc++.h>
    using namespace std;
    int mapp[2000][2000];
    int n,m;
    int ans=0;
    int sum[2000][2000];
    struct node
    {
    	int H,l;
    };
    stack<node> S;
    void get()
    {
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)
    		{
    			int len=0;
    			while(S.size()&&S.top().H>sum[i][j])
    			{
    				 len+=S.top().l;
    				 ans=max(ans,len*S.top().H);
    				 S.pop();
    			}
    			S.push(node{sum[i][j],len+1});
    		}
    		
    		int len=0;
    		while(S.size())
    		{
    			len+=S.top().l;
    			ans=max(ans,len*S.top().H);
    			S.pop();
    		}
    	}
    }
    void ssum()
    {
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)
    		{
    			sum[i][j]=(mapp[i][j]?sum[i-1][j]+1:0);
    		}
    	}
    }
    int main()
    {
    	char c;
    
    	cin>>n>>m;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++)
    		{
    			c=getchar();
    			while(c!='F'&&c!='R')
    			{
    				c=getchar();
    			}
    			if(c=='F')
    			{
    				mapp[i][j]=1;
    			}
    			else
    			mapp[i][j]=0;
    		}
    	}
    	ssum();
    	get();
    	cout<<3*ans;
    	
    }
    

    2 DP
    对于每个点考虑
    当前这个点向左所能延伸到到最远的距离就是 他上面和他的离得最近的距离
    dp一下即可


    来道经典题:
    翻转矩阵
    何老板给你一个H*W的网格棋盘,每个方格都被涂上了黑色或白色。
    你可以进行任意次下列操作:
      任选一行(或一列),将该行(列)的方格颜色翻转,即白色变黑,黑色变白。
    何老板希望你能在棋盘上找出最大的一个黑色矩形。该矩形中的方格全是黑色,请你输出该矩形的面积。

    注意到能够成为矩形到充要条件是每个2$ imes$2 的小矩形异或值为0
    所以我们考虑构建一个新的矩阵
    找最大的面积

    刀剑映出了战士的心。而我的心,漆黑且残破
  • 相关阅读:
    c++11:智能指针
    C++11:右值引用
    结构体与联合体
    数组与指针的区别?
    堆和栈的理论知识
    笔试点杂烩
    2、8、10、16进制输出
    单链表的反转
    签约新国都
    Linux下使用autoconf 和 automake 编译简单的HelloWorld
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11558341.html
Copyright © 2020-2023  润新知