洛谷 P4147 玉蟾宮 題解【懸線dp】

原題地址

蛤,今天正好學習一下懸線dp,寫了個板子題。
l[i][j]l[i][j]表示能延伸的最左的位置的列,r[i][j]r[i][j]表示能掩上的最右位置的列,up[i][j]up[i][j]表示向上擴展最大長度。
不難得到:
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 若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
顯然,當然是能延伸就延伸。
接下來考慮行之間關係:
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 若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
其實在列之間就是考慮縮,即可行性,我們需要選最小的l[i][j]和r[i][j]。(不懂珂以畫畫圖)
諤諤,結束了
Code\color{blue}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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章