单调栈总结 来自poj
来源:互联网 发布:怎么在淘宝卖视频会员 编辑:程序博客网 时间:2024/06/16 10:27
单调栈不用再多介绍,我这里是自己写的实现,可能没有很大得优化,但也懒得去看别人怎么优化了~
到现在做的题都是大同小异,把代码改改就能迅速的过。
单调栈能解决的问题——求一个以某个值为最小值的区间!
这个性质广泛的用于一种题型的解决。
一类连续最大区域的问题。
poj 2082
这题题意很模糊,我看不下去,直接看看别人的解释,原来就是合并矩形,刚开始无从下手,后来发现这不就是问怎样把一个矩形尽量的和其他的矩形合并得到更大的矩形吗?这就很顺利的想到单调栈咯。
#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>#include <algorithm>#include <vector>#include <limits.h>#include <queue>#include <stack>using namespace std;struct C{ int b,e;}c[50010];struct S{ long long num,id;}s[50010];long long dp[50010];long long a[50010],b[50010],ans,sum;int main(){ int n,i,j,top; while(scanf("%d",&n)!=EOF&&n!=-1) { dp[0] = 0; ans = 0; for(i = 1;i <= n;i ++) {scanf("%I64d%I64d",&a[i],&b[i]);dp[i] = dp[i-1]+a[i];} s[0].num = -1;s[0].id = 0; top = 0; for(i = 1;i <= n;i ++) { for(j = top;j >= 0;j --) { if(b[i] > s[j].num) break; else { c[s[j].id].e = i-1; } } s[j+1].num = b[i];s[j+1].id = i; top = j+1;c[i].b = s[top-1].id+1; } for(j = 0;j <= top;j ++) c[s[j].id].e = n; for(i = 1;i <= n;i ++) { //cout<<c[i].num<<" "<<c[i].b<<" "<<c[i].e<<endl; sum = dp[c[i].e] - dp[c[i].b-1]; sum *= b[i]; if(sum > ans) ans =sum; } printf("%I64d\n",ans); }}
poj 2559
这道题就更明显啦~
#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>#include <algorithm>#include <vector>#include <limits.h>#include <queue>#include <stack>using namespace std;struct S{ int num,id;}s[100010];struct C{ int num,b,e;}c[100010];long long dp[100010];int main(){ long long a[100010],i,j,n,top; long long ans = -1,b,e,sum; while(scanf("%I64d",&n)!=EOF&&n!=0) { ans = -1; dp[0] = 0; for(i = 1;i <= n;i ++) {scanf("%I64d",&a[i]);c[i].num = a[i];dp[i] = dp[i-1]+a[i];} s[0].num = -1;s[0].id = 0; top = 0; for(i = 1;i <= n;i ++) { for(j = top;j >= 0;j --) { if(a[i] > s[j].num) break; else { c[s[j].id].e = i-1; } } s[j+1].num = a[i];s[j+1].id = i; top = j+1;c[i].b = s[top-1].id+1; //for(j = 0;j <= top;j ++) cout<<s[j].num<<" ";cout<<endl; } for(j = 0;j <= top;j ++) c[s[j].id].e = n; for(i = 1;i <= n;i ++) { //cout<<c[i].num<<" "<<c[i].b<<" "<<c[i].e<<endl; sum = (c[i].e - c[i].b+1)*a[i]; //sum *= c[i].num; if(sum > ans) {ans =sum;b = c[i].b;e = c[i].e;} } printf("%I64d\n",ans); }}
poj 3494
这题有点难想到用单调栈,我还以为是DP,其实和上面的都一样的解法,就是要枚举一下每行咯,一开始的初始化,用到的是h数组也很重要。
#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>#include <algorithm>#include <vector>#include <limits.h>#include <queue>#include <stack>using namespace std;struct S{ int num,id;}s[2010];struct C{ int b,e;}c[2010];int h[2010][2010],a[2010];int main(){ bool mp[2010]; int i,j,n,m,k,top; while(scanf("%d%d",&n,&m)!=EOF) { memset(h,0,sizeof(0)); for(i = 1;i <= n;i ++){ for(j = 1;j <= m;j ++) { scanf("%d",&mp[j]); if(mp[j]) { h[i][j] = h[i-1][j]+1; } else { h[i][j] = 0; } } } int sum,ans,ans1; ans1 = 0; for(k = 1;k <= n;k ++) { for(i = 1;i <= m; i ++) a[i] = h[k][i]; s[0].num = -1;s[0].id = 0; top = 0;ans = 0; for(i = 1;i <= n;i ++) { for(j = top;j >= 0;j --) { if(a[i] > s[j].num) break; else { c[s[j].id].e = i-1; } } s[j+1].num = a[i];s[j+1].id = i; top = j+1;c[i].b = s[top-1].id+1; //for(j = 0;j <= top;j ++) cout<<s[j].num<<" ";cout<<endl; } for(j = 0;j <= top;j ++) c[s[j].id].e = n; for(i = 1;i <= n;i ++) { //cout<<c[i].b<<" "<<c[i].e<<endl; sum = (c[i].e - c[i].b+1)*a[i]; //sum *= c[i].num; if(sum > ans) {ans =sum;} } if(ans > ans1) ans1 =ans; } printf("%d\n",ans1); }}
- 单调栈总结 来自poj
- 单调队列 单调栈总结
- 单调队列,单调栈总结
- 【单调栈】POJ 3250
- poj 2796#单调栈
- POJ 2559 单调栈
- POJ 2559 单调栈
- POJ 2796 单调栈~
- poj 2796(单调栈)
- poj 2559(单调栈)
- poj 2559 单调栈
- poj 2059 单调栈
- POJ 2559 单调栈
- poj 2796 单调栈
- poj 2796 单调栈
- POJ 3250 单调栈
- poj 2559 单调栈
- POJ 3044单调栈
- 逗号操作符的意义
- Oracle创建用户、表空间、导入导出、...命令
- Hibernate3.6中用Annotation来实现实体类与数据库表的映射关系
- 實參 形參 指針 四種寫法
- 临时表和表变量
- 单调栈总结 来自poj
- Oracle创建简单的触发器练习
- struts2学习之文件上传
- google-logo-20120501
- 一台手机玩转你所有的社交生活(Android版)
- css中选择器的使用
- Myeclipse优化
- SQLServer 2008 R2在对象资源管理器中隐藏系统对象
- 3. Scilab程序设计