洛谷 P4147 玉蟾宫 题解【悬线dp】

2 篇文章 0 订阅
1 篇文章 0 订阅

原题地址

蛤,今天正好学习一下悬线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]==Fa[i][j1]==Fl[i][j]=l[i][j1]a[i][j]==Fa[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 i2a[i][j]==Fa[i1][j]==Fl[i][j]=max(l[i][j],l[i1][j])r[i][j]=min(r[i][j],r[i1][j])up[i][j]=up[i1][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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值