简单单调栈的应用

简单单调栈的运用:

首先的话就是poj上面的一维问题,最开始的想法
当然是暴力但是自己一开始也是没有想到什么好点
的想法去暴力,那就来看下别人的想法的暴力思想吧
首先就是以一个矩形位标准,分别向左和右扩展,找到
左右第一个比他小的,中间的面积直接更新即可。
code如下:当然这个是超时的,接下来的话就是自己
学习的单调栈的应用啦
o(n^2)的超时代码:

#include<iostream>
using namespace std;
typedef long long ll;
#define M 10000
ll num[M];
int main(){
	ll n,i,l,r;
	while(cin>>n){
		ll ans=0,res=0;
		if(n==0) break;
		for(i=0;i<n;i++)
			scanf("%lld",&a);
		for(i=0;i<n;i++){
			l=i;
			r=i;
			while(l>=0&&num[l-1]>=a)l--;
			while(r<n&&num[r+1]>=a)r++;
			ans=(r-l+1)*a;
			res=max(res,ans);
		}
		cout<<res<<endl;
	}	
	return 0;
}

顺便学到了,
virtual oj(利用爬虫爬各oj的题目然后你就可以用一个账号写各oj的题目哟,还可以爬到国外的oj) 的话c++的头文件是不支持 c语言的scanf语句的
单调栈的代码如下:
学习到了好多的东西,了解到了单调栈不一定非要用栈写,也可以用数组模拟,有时候这种方法的效果可以更好,
还有就是学懂了那个单调栈的话,所有的元素都是最多入栈出栈一次,o(n)的时间复杂度;

数组模拟版本:

#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;
typedef long long ll;
const ll  M=100100;
	ll hi[M];
	ll w[M]; 
int main(){
	ll n,a,ans,top,i,cnt;
	while(cin>>n){
	ll	top = 0; ll ans = 0;
		if(n==0) break;
		for(i=0;i<n;i++){
			scanf("%lld",&a);
			if(top==0||a>hi[top]){
				w[++top] = 1;
				hi[top] = a;	
			} 
			else {
					cnt = 0;
	
				while(top > 0&&a<= hi[top]){
					cnt += w[top];
					ans = max(ans,hi[top]*cnt);
					top--;
				}
				hi[++top]=a;
				w[top] = cnt+1;
			}
		/*整了半天终于弄明白为什么要用cnt来计数了,
	这样就计算出了下一个 要加入的数的左边界右多少个数了;这也就是我下面代码的错误的地方
	 */ 
			/*	while(top > 0&&a<= hi[top]){
						ans = max(ans,hi[top]*w[top]);
						w[top-1]+=w[top];
						top--;
				}
				hi[++top]=a;
				w[top] = w[top-1]+1;
				}*/	
			
		}
		 cnt = 0;
		while(top>0){
			cnt += w[top];
			ans = max(ans,cnt*hi[top]);
			top--;
		}
		cout<<ans<<endl;
	}
	return 0;
} 

//vecter容器版本;就他们直接用stack储存右边界,然后再去查找对应的高度。
//顺便系统的学习了下vecter容器;

还有一种就是左右扫描版本的,这种的话好像运用了动态规划的思想,然后做到了o(n)的时间复杂度,
这种储存结果再利用的动规是值得学习的。本人比较懒就直接看别人的博客吧;
https://www.cnblogs.com/boring09/p/4231906.html

然后就是二维的单调栈的应用了;暑假的时候写过这样的题目,再来复习一遍吧;
poj 3493题:
http://poj.org/problem?id=3494
这一题的话,自己感觉其实就是在那个上面的基础上需要压缩一下,把二维的压缩成一维的就可以了,
接下来的话其实就是在没扫完一行后就进行压栈和入栈的操作,当然这只是自己第一个的主观感受,具体的话
就需要代码来说话了。这样的想法的话就是o(n^2)的复杂度了,应该可以写吧;
哈哈哈,实践检验到自己的想法是正确的虽然代码长了点但是结果是正确的;

#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;
typedef long long ll;
ll n,m,ans,top,i,cnt,j,k;
const ll  M=100100;
	ll hi[M];
	ll w[M]; 
	ll a[2007];
	ll ma[2007][2007];
	ll check(){//check函数就是上面的一维单调栈的代码; 
		
		ll	top = 0; ll ans = 0;ll d;
	
		for(d=0;d<m;d++){
			
			if(top==0||a[d]>hi[top]){
				w[++top] = 1;
				hi[top] = a[d];	
			} 
			else {
					cnt = 0;
	
				while(top > 0&&a[d]<= hi[top]){
					cnt += w[top];
					ans = max(ans,hi[top]*cnt);
					top--;
				}
				hi[++top]=a[d];
				w[top] = cnt+1;
			}	
		}
		 cnt = 0;
		while(top>0){
			cnt += w[top];
			ans = max(ans,cnt*hi[top]);
			top--;
		}
		
		return ans;	
		}
int main(){
	
ll res;
	while(cin>>n>>m){
		for(j=0;j<m;j++){
			scanf("%lld",&ma[0][j]);
			a[j]=ma[0][j];
		}
		res=check();
		for(j=1;j<n;j++){
			for(k=0;k<m;k++){
				scanf("%lld",&ma[j][k]);
				if(ma[j][k]==0)a[k]=0;
				else if(ma[j][k]==1){
					if(a[k]!=0)a[k]++;
					else a[k]=1;	
				}
			
			}
		res=max(res,check());
}
cout<<res<<endl;
	}
	return 0;
} 在这里插入代码片

组长的非常简洁的代码: https://www.cnblogs.com/wizarderror/p/11232097.html
参考博客:个人觉得他们写的好;
https://www.cnblogs.com/qixingzhi/p/9497208.html
https://www.cnblogs.com/lichen782/p/leetcode_Largest_Rectangle_in_Histogram.html
https://www.cnblogs.com/boring09/p/4231906.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值