E. Nanosoft(dp)

http://codeforces.com/problemset/problem/1301/E

题意:

给出一个图,一个合格的正方形为左上角R,右上角G,右下角B,左下角Y,各占1/4。每次询问给出的长方形面积内的最大合格正方形。

解析:

数据结构想不出,dp做是水题。

处理 d p [ i ] [ j ] [ l e n ] dp[i][j][len] 以(i,j)为左上角len长度的正方形区域内的最大合格正方形面积。

转移简单。
查询时for一遍即可。

代码:

/*
 *  Author : Jk_Chen
 *    Date : 2020-03-19-13.24.30
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<' '<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=509;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

int Max(int a){return a;}
template<typename A,typename... Args>
int Max(A a,Args... args){
    return max(a,Max(args...));
}

char x[maxn][maxn];
int ct[4][maxn][maxn];
int id(char x){
    if(x=='R')return 0;
    if(x=='G')return 1;
    if(x=='B')return 2;
    return 3;
}
int sum(int id,int x1,int y1,int x2,int y2){
    return ct[id][x2][y2]-ct[id][x1-1][y2]-ct[id][x2][y1-1]+ct[id][x1-1][y1-1];
}
int dp[maxn][maxn][maxn];

int main(){
    int n=rd,m=rd,q=rd;
    rep(i,1,n)scanf("%s",x[i]+1);
    rep(i,1,n)rep(j,1,m){
        rep(k,0,3)
            ct[k][i][j]=ct[k][i-1][j]+ct[k][i][j-1]-ct[k][i-1][j-1];
        ct[id(x[i][j])][i][j]++;
    }
    rep(len,2,min(n,m)){
        rep(i,1,n){
            if(i+len-1>n)break;
            rep(j,1,m){
                if(j+len-1>m)break;

                if(len%2==0&&
                   sum(0,i,j,i+len/2-1,j+len/2-1)==len*len/4&&
                   sum(3,i+len/2,j,i+len-1,j+len/2-1)==len*len/4&&
                   sum(1,i,j+len/2,i+len/2-1,j+len-1)==len*len/4&&
                   sum(2,i+len/2,j+len/2,i+len-1,j+len-1)==len*len/4)
                    dp[i][j][len]=len*len;
                else
                    dp[i][j][len]=Max(dp[i][j][len-1],dp[i+1][j][len-1],
                                      dp[i][j+1][len-1],dp[i+1][j+1][len-1]);
            }
        }
    }
    while(q--){
        int x1=rd,y1=rd,x2=rd,y2=rd;
        int ans=0;
        int len=min(x2-x1+1,y2-y1+1);
        rep(i,x1,x2){
            if(i+len-1>x2)break;
            ans=max(ans,dp[i][y1][len]);
        }
        rep(i,y1,y2){
            if(i+len-1>y2)break;
            ans=max(ans,dp[x1][i][len]);
        }
        printf("%d\n",ans);
    }


    return 0;
}

/*_________________________________________________________end*/

发布了773 篇原创文章 · 获赞 345 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/104990074