DP【洛谷P3135】[USACO16JAN]堡哞Fort Moo

【洛谷P3135】[USACO16JAN]堡哞Fort Moo

Bessie和她的朋友Elsie正在建筑一个堡垒,与任何一个好的堡垒一样,这个需要一个强固的框架。Bessie想造一个轮廓是1m宽的空心矩形框架,这样堡垒就可以造在框架上了。

Bessie以及选了一个地点建筑堡垒,一片N*M(1<=N,M<=200)的平地。不幸的是,这个地方有一些沼泽地而不可以支撑框架。请帮助Bessie决定最大她可以用堡垒覆盖的区域(即支撑框架的区域),而且避免框架在任何一块沼泽地上。

朴素暴力用前缀和优化成(n^4)

枚举两行,扫一遍m找出最左一列和最右一列,优化为(n^3)

code:

#include <iostream>
#include <cstdio>

using namespace std;

const int wx=217;

inline int read(){
	int sum=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
	return sum*f;
}

int ans,n,m;

int a[wx][wx],b[wx][wx],c[wx][wx],d[wx][wx];

char cc[wx];

void slove(int first,int second){
	int flag=0,fltot=0;
	for(int i=1;i<=m;i++){
		if(!b[first][i]||!b[second][i])continue;
		if(!b[first][i-1]||!b[second][i-1])flag=i;
		if(a[second][flag]-a[first][flag]+1!=second-first+1)flag++;
		if(a[second][i]-a[first][i]+1==second-first+1){
			ans=max(ans,(second-first+1)*(i-flag+1));
		}
	}
}

int main(){
	n=read(); m=read();
	for(int i=1;i<=n;i++){
		scanf("%s",cc+1);
		for(int j=1;j<=m;j++){
			if(cc[j]=='X')continue;
			a[i][j]=a[i-1][j]+1;
			b[i][j]=b[i][j-1]+1;
		}
	}
	for(int i=n;i>=1;i--){
		for(int j=m;j>=1;j--){
			if(!a[i][j])continue;
			c[i][j]=c[i+1][j]+1;
			d[i][j]=d[i][j+1]+1;
		}
	}
	/*
	$n^4暴力$
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(!a[i][j])continue;
			for(int k=i;k<=n;k++){
				for(int l=j;l<=m;l++){
					if(!a[k][l])continue;
					if(k-i+1<=a[k][l]&&l-j+1<=b[k][l]&&k-i+1<=c[i][j]&&l-j+1<=d[i][j]){
						ans=max(ans,(k-i+1)*(l-j+1));
					}
				}
			}
		}
	}
	*/
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			slove(i,j);
		}
	}
	printf("%d
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/wangxiaodai/p/9843613.html