1 条题解
-
0
自动搬运
来自洛谷,原作者为

114514wxy
这个家伙不懒,什么也没有留下搬运于
2025-08-24 22:34:39,当前版本为作者最后更新于2024-03-17 09:51:32,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
解法很简单:先跑出来满足 YF 条件的 矩阵,把左上角置为 ,最后求全为 的矩阵的最大值。
来论证两个东西:全为 1 的矩阵为什么是 Sept 矩阵以及怎么求最大值。
那么第一个,我们不妨以一个 的矩阵入手,这个矩阵的两个子 矩阵都是 YF 矩阵。那么就有
和
。
不等式两边同时相加并消去一下,可以得到
这个就是满足 YF 的 矩阵了。
同理也可以推广到更大的矩阵。
第一个证毕。
至于第二个,求解本类 矩阵中全为 的矩阵的最大面积可以用悬线法。对于一个 的 矩阵,具体操作如下:
随着枚举到第 行的过程,我们可以对于每一列 想象一条悬线,从 的位置向上延伸,直到第一个位置(也就是最靠下的位置)使得 ,其中 。将这条悬线的长记为 。接下来,对于本 ,分别定义
$l_j=\text{max}(k) \text{ 其中}k\in[1,j-1]\text{ 且 } h_{k-1}<h_j$
以及
$r_j=\text{min}(k) \text{ 其中}k\in[j+1,m]\text{ 且 } h_{k+1}<h_j$
这分别意味着这条悬线可以向左或向右“推广到”的距离。
同时,可以认为 。
至于计算过程,以 数组举例,应当先赋值 ,之后尝试向左推广。不难发现,
若
则可以有
这是因为由上面的条件可以知道:至少一直到 的位置,对于 都会满足 。边界终止条件为 。
对于 数组的计算同理。
如此,对于一个 ,用其上的悬线“推广”出来的矩阵面积就是 。
注意到我们是在缩水过的 矩阵上进行的悬线,最终得出的面积应当是上式两个乘数各自 后的值。
代码很简单。
#include<bits/stdc++.h> using namespace std; const int N=1e3+10; int n,m,a[N][N],ans; int h[N],l[N],r[N]; bool cd[N][N]; int main(){ cin>>n>>m; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) scanf("%d",&a[i][j]); --n,--m; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) cd[i][j]=(a[i][j]+a[i+1][j+1]<=a[i][j+1]+a[i+1][j]); for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j) l[j]=r[j]=j,h[j]=(cd[i][j])?h[j]+1:0; for(int j=1;j<=m;++j) while(l[j]!=1&&h[l[j]-1]>=h[j]) l[j]=l[l[j]-1]; for(int j=m;j>=1;--j) while(r[j]!=m&&h[r[j]+1]>=h[j]) r[j]=r[r[j]+1]; for(int j=1;j<=m;++j) ans=max(ans,(r[j]-l[j]+2)*(h[j]+1)); } cout<<ans<<endl; return 0; }
- 1
信息
- ID
- 7285
- 时间
- 900ms
- 内存
- 32MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者