P3400 仓鼠窝 题解-单调栈典题
20231026
P3400 仓鼠窝 题解-单调栈典题
Statement
输出 01 矩阵中不含 0 的子矩阵的个数。
Solution
很妙的做法,典题,于是写了题解。
做法也很简单,就是你枚举每一个节点作为右上角的点的方案数,
发现其实有很多无用的点,比如有一个在你后面且比你高的点,
这样你就被淘汰了。
于是对于那些有用的点,我们可以直接用单调栈维护,
同时维护一个前缀和就是对答案的贡献。
具体实现就是枚举每一行,
再从左往右扫从而计算答案即可。
代码非常短。。。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=3e3+5;
int n,m,a[N][N],d[N],st[N],tp=0;
ll ans=0,s[N];
int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int main(){
/*2023.10.26 H_W_Y P3400 仓鼠窝 单调栈*/
n=read();m=read();
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=read();
for(int i=1;i<=n;i++,tp=0)
for(int j=1;j<=m;j++){
if(!a[i][j]) d[j]=i;
while(tp>0&&d[st[tp]]<d[j]) tp--;
st[++tp]=j;
ans+=(s[tp]=s[tp-1]+(i-d[st[tp]])*(st[tp]-st[tp-1]));
}
printf("%lld\n",ans);
return 0;
}
Conclusion
矩阵个数统计我们可以尝试维护每一个点为右上角的合法矩阵数量。
本文作者:H_W_Y
本文链接:https://www.cnblogs.com/H-W-Y/p/P3400.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
标签:
,
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具