专栏文章
题解:P12501 「ROI 2025 Day1」奥林匹克楼梯
P12501题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minpx2g1
- 此快照首次捕获于
- 2025/12/02 06:25 3 个月前
- 此快照最后确认于
- 2025/12/02 06:25 3 个月前
分析
得到此数组后,开始下一步。
解决
发现自右向左维护一个严格单调递增的栈(存下标)比较方便。
对于每一个新加入的数,若比栈顶元素大,放入,否则不断弹出直到栈为空或比栈顶元素大。此时,若栈为空,则它为最小值,那么新更新的就是长为 ,宽为 的矩阵。若栈不为空,则更新的矩形为长为 ,宽为 的矩形。
代码
CPP#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<string>
#define int long long
#define N 4000005
using namespace std;
inline void read(int &x){
int f=1; x=0; char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+(ch-'0');
ch=getchar();
}
x*=f;
}
inline void write(long long x){
if(x<0)
putchar('-'),x=-x;
if(x>=10)
write(x/10);
putchar(x%10+'0');
}
int n,m;
vector<int> a[N],dp[N];
int s[N],top,f[N];
int fans;
signed main(){
read(n); read(m);
for(int i=0;i<=n+1;i++)
a[i].resize(m+1),dp[i].resize(m+1);
for(int i=1;i<=n;i++){
string s; cin>>s; s=' '+s;
for(int j=1;j<=m;j++)
a[i][j]=s[j]-'0';
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j]==1)
dp[i][j]=dp[i-1][j]+1;
s[0]=m;//记得初始化
for(int i=1;i<=n;i++){
top=0;//清空
int res=0,ans=0;
for(int j=m;j>=1;j--){
while(dp[i][j]<=dp[i][s[top]]&&top)
top--;//小于就弹出
if(top)//不为空
f[j]=f[s[top]]+(s[top]-j)*dp[i][j];//可续接
else//为空
f[j]=(m-j+1)*dp[i][j];
s[++top]=j;//加入
ans=max(ans,f[j]);//更新
}
fans=max(fans,ans);
}
write(fans);
return 0;
}
后记
听说考前发题解会 ++RP。
求过。
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...