zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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
    ",++Case,ans);
         }
         return 0;
    }
  • 相关阅读:
    HDOJ 2095 find your present (2)
    HDOJ 2186 悼念512汶川大地震遇难同胞——一定要记住我爱你
    九度 1337 寻找最长合法括号序列
    九度 1357 疯狂地Jobdu序列
    HDOJ 1280 前m大的数
    九度 1343 城际公路网
    九度 1347 孤岛连通工程
    HDOJ 2151 Worm
    九度 1342 寻找最长合法括号序列II
    九度 1346 会员积分排序
  • 原文地址:https://www.cnblogs.com/hua-dong/p/7669032.html
Copyright © 2011-2022 走看看