HDU2870 最大窗口面积(单调队列优化)
HDU1506
HDU2870
HDU4328
以前做的是单调队列的方法,现在试一试DP
注意的是对于i,向左延伸的L[i]到i不一定是单调的,比如1 3 2 1 2,对于i=4,L[i]=1而是2所以不能简单的和左边第一个比较
错: if(a[i]<=a[i-1]) L[i]=L[i-1]+1;
HDU1506
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<memory.h>
using namespace std;
#define LL long long
const int maxn=100010;
LL L[maxn],R[maxn],h[maxn],ans,tmp;
int main()
{
int n,i,t;
while(~scanf("%d",&n))
{
if(n==0) return 0;
for(i=1;i<=n;i++) scanf("%lld",&h[i]);
L[1]=1;R[n]=n;
for(i=2;i<=n;i++) {
t=i;
while(t>1&&h[t-1]>=h[i]) t=L[t-1];
L[i]=t;
}
for(i=n-1;i>=1;i--){
t=i;
while(t<n&&h[t+1]>=h[i]) t=R[t+1];
R[i]=t;
}
ans=h[1];
for(i=1;i<=n;i++){
tmp=h[i]*(R[i]-L[i]+1);
if(tmp>ans) ans=tmp;
}
printf("%lld\n",ans);
}
return 0;
}
HDU2870
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<memory.h>
#include<cmath>
using namespace std;
char c[1010][1010];
int L[1010],R[1010],D[1010][1010];
int n,m,ans;
bool _w(char a,char b){
if(b=='a'&&(a=='a'||a=='w'||a=='y'||a=='z')) return true;
if(b=='b'&&(a=='b'||a=='w'||a=='x'||a=='z')) return true;
if(b=='c'&&(a=='c'||a=='y'||a=='x'||a=='z')) return true;
return false;
}
void _get(char u)
{
int i,j,t;
memset(D,0,sizeof(D));
memset(L,0,sizeof(L));
memset(R,0,sizeof(R));
for(i=n;i>=1;i--)
for(j=1;j<=m;j++)
if(_w(c[i][j],u))
D[i][j]=D[i+1][j]+1;
for(i=1;i<=n;i++){
L[1]=1;R[m]=m;
for(j=2;j<=m;j++){
t=j;
while(t>1&&D[i][j]<=D[i][t-1]) t=L[t-1];
L[j]=t;
}
for(j=m-1;j>=1;j--){
t=j;
while(t<m&&D[i][j]<=D[i][t+1]) t=R[t+1];
R[j]=t;
}
for(j=1;j<=m;j++){
ans=max(ans,(R[j]-L[j]+1)*D[i][j]);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++) scanf("%s",c[i]+1);
ans=0;
_get('a');
_get('b');
_get('c');
printf("%d\n",ans);
}
return 0;
}
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<memory.h>
#include<cmath>
using namespace std;
char c[1010][1010];
int L[1010],R[1010],D[1010][1010];
int n,m,ans;
void _getd(char u)
{
int i,j;
memset(D,0,sizeof(D));
for(i=n;i>=1;i--)
for(j=1;j<=m;j++)
if(c[i][j]==u)
D[i][j]=D[i+1][j]+1;
}
void _get1()
{
int i,j;
memset(D,0,sizeof(D));
for(i=n;i>=1;i--)
for(j=1;j<=m;j++){
if((i+j)%2==1&&c[i][j]=='B')
D[i][j]=D[i+1][j]+1;
if((i+j)%2==0&&c[i][j]=='R')
D[i][j]=D[i+1][j]+1;
}
}
void _get2()
{
int i,j;
memset(D,0,sizeof(D));
for(i=n;i>=1;i--)
for(j=1;j<=m;j++){
if((i+j)%2==1&&c[i][j]=='R')
D[i][j]=D[i+1][j]+1;
if((i+j)%2==0&&c[i][j]=='B')
D[i][j]=D[i+1][j]+1;
}
}
void _get(char u)
{
int i,j,t;
if(u=='X') _get1();
else if(u=='Y') _get2();
else _getd(u);
for(i=1;i<=n;i++){
L[1]=1;R[m]=m;
for(j=2;j<=m;j++){
t=j;
while(t>1&&D[i][j]&&D[i][j]<=D[i][t-1]) t=L[t-1];
L[j]=t;
}
for(j=m-1;j>=1;j--){
t=j;
//为什么不加D[i][j]就一直WA??? 因为高为0时是两条线段,不是矩形。。。
while(t<m&&D[i][j]&&D[i][j]<=D[i][t+1]) t=R[t+1];
R[j]=t;
}
for(j=1;j<=m;j++){
ans=max(ans,2*((R[j]-L[j]+1)+D[i][j]));
}
}
}
int main()
{
int T,Case=0;
scanf("%d",&T);
while(T--){
ans=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%s",c[i]+1);
_get('R');_get('B');_get('X');_get('Y');
printf("Case #%d: %d\n",++Case,ans);
}
return 0;
}
It is your time to fight!