原题地址
蛤,今天正好学习一下悬线dp,写了个板子题。
用
l
[
i
]
[
j
]
l[i][j]
l[i][j]表示能延伸的最左的位置的列,
r
[
i
]
[
j
]
r[i][j]
r[i][j]表示能掩上的最右位置的列,
u
p
[
i
]
[
j
]
up[i][j]
up[i][j]表示向上扩展最大长度。
不难得到:
若
a
[
i
]
[
j
]
=
=
F
且
a
[
i
]
[
j
−
1
]
=
=
F
l
[
i
]
[
j
]
=
l
[
i
]
[
j
−
1
]
若
a
[
i
]
[
j
]
=
=
F
且
a
[
i
]
[
j
+
1
]
=
=
F
r
[
i
]
[
j
]
=
r
[
i
]
[
j
+
1
]
u
p
[
i
]
[
j
]
=
1
若a[i][j]==F 且a[i][j-1]==F\\ l[i][j]=l[i][j-1]\\ 若a[i][j]==F且a[i][j+1]==F\\ r[i][j]=r[i][j+1]\\ up[i][j]=1
若a[i][j]==F且a[i][j−1]==Fl[i][j]=l[i][j−1]若a[i][j]==F且a[i][j+1]==Fr[i][j]=r[i][j+1]up[i][j]=1
显然,当然是能延伸就延伸。
接下来考虑行之间关系:
若
i
≥
2
且
a
[
i
]
[
j
]
=
=
F
且
a
[
i
−
1
]
[
j
]
=
=
F
l
[
i
]
[
j
]
=
m
a
x
(
l
[
i
]
[
j
]
,
l
[
i
−
1
]
[
j
]
)
r
[
i
]
[
j
]
=
m
i
n
(
r
[
i
]
[
j
]
,
r
[
i
−
1
]
[
j
]
)
u
p
[
i
]
[
j
]
=
u
p
[
i
−
1
]
[
j
]
+
1
若i \ge 2且a[i][j]==F且a[i-1][j]==F\\ l[i][j]=max(l[i][j],l[i-1][j])\\ r[i][j]=min(r[i][j],r[i-1][j])\\ up[i][j]=up[i-1][j]+1
若i≥2且a[i][j]==F且a[i−1][j]==Fl[i][j]=max(l[i][j],l[i−1][j])r[i][j]=min(r[i][j],r[i−1][j])up[i][j]=up[i−1][j]+1
其实在列之间就是考虑缩,即可行性,我们需要选最小的l[i][j]和r[i][j]。(不懂珂以画画图)
谔谔,结束了
C
o
d
e
\color{blue}Code
Code:
# include <bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m;
char a[N][N];
int l[N][N],r[N][N],up[N][N];
int main(void)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin >> a[i][j];
l[i][j]=r[i][j]=j,up[i][j]=1;
}
}
for(int i=1;i<=n;i++)
{
for(int j=2;j<=m;j++)
{
if(a[i][j]=='F'&&a[i][j-1]=='F')
l[i][j]=l[i][j-1];
}
for(int j=m-1;j>=1;j--)
{
if(a[i][j]=='F'&&a[i][j+1]=='F')
r[i][j]=r[i][j+1];
}
}
int maxl=INT_MIN;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(i>=2&&a[i][j]=='F'&&a[i-1][j]=='F')
{
up[i][j]=up[i-1][j]+1;
l[i][j]=max(l[i][j],l[i-1][j]) ;
r[i][j]=min(r[i][j],r[i-1][j]) ;
}
int w=r[i][j]-l[i][j]+1;
int h=up[i][j];
maxl=max(maxl,w*h) ;
}
}
cout<<3*maxl<<endl;
return 0;
}
对了,说一下,最后答案要乘3,害得我正解还调试一小时ee