zoukankan      html  css  js  c++  java
  • hdu 4328 极大子矩形加正方形DP

    题意:给出一个蛋糕,蛋糕有两种颜色组成,同一种颜色的可以切矩形,红蓝相间的可以切正方形。问你切出的蛋糕的最大周长

    对于同一种颜色,很显然就是最大子矩形了。用悬线法搞定

    对于红蓝相间的正方形,可以用DP解决。

    定义dp[i][j]表示,以i,j为正方形右下角点的时候的最大边长。显然dp[i][j]=min(dp[i-1][j],dp[i][j-1])+1,但是有一个前提,那就是

    map[i][j]!=map[i-1][j] && map[i][j]!=map[i][j-1]

    另外还需要注意一点就是,对角线上的元素必须是相同的。比如

    BB

    BR 如果不注意判断对角线的元素,那么正方形会得出2*2

    View Code
      1 #include<iostream>
      2 #include<string>
      3 #include<algorithm>
      4 using namespace std;
      5 
      6 char v[1002][1002];
      7 int h[1002],l[1002],r[1002],lm,rm;
      8 int n,m;
      9 
     10 int get_rectange(char c) //悬线法
     11 {
     12     int i,j,ans,temp;
     13     ans=0;
     14     for(i=1;i<=m;i++)
     15     {
     16         h[i]=0;l[i]=1;r[i]=m;
     17     }
     18     for(i=1;i<=n;i++)
     19     {
     20         lm=1;
     21         for(j=1;j<=m;j++)
     22         {
     23             if(v[i][j]==c)
     24             {
     25                 h[j]++;
     26                 if(lm>l[j])
     27                     l[j]=lm;
     28             }
     29             else
     30             {
     31                 h[j]=0;
     32                 l[j]=1;
     33                 r[j]=m;
     34                 lm=j+1;
     35             }
     36         }
     37         rm=m;
     38         for(j=m;j>=1;j--)
     39         {
     40             if(rm<r[j])
     41                 r[j]=rm;
     42             if(h[j])
     43             {
     44                 temp=2*(r[j]-l[j]+1)+2*h[j];
     45                 if(temp>ans)
     46                     ans=temp;
     47             }
     48             else
     49                 rm=j-1;
     50         }
     51     }
     52     return ans;
     53 }
     54 
     55 int dp[1002][1002];
     56 
     57 int min(int a,int b)
     58 {
     59     return a<b?a:b;
     60 }
     61 
     62 int DP()
     63 {
     64     memset(dp,0,sizeof(dp));
     65     int i,j,k,ans=0;
     66     for(i=1;i<=n;i++)
     67     {
     68         for(j=1;j<=m;j++)
     69         {
     70             dp[i][j]=1;
     71             if(v[i-1][j]!=v[i][j] && v[i][j]!=v[i][j-1])
     72             {
     73                 k=min(dp[i-1][j],dp[i][j-1]);
     74                 if(v[i-k][j-k]==v[i][j]) //判断对角线
     75                     k++;
     76                 if(k>dp[i][j])
     77                     dp[i][j]=k;
     78             }
     79             if(dp[i][j]*4>ans)
     80                 ans=dp[i][j]*4;
     81         }
     82     }
     83     return ans;
     84 }
     85 
     86 int main()
     87 {
     88     int i,j,cas,ansR,ansB,ansC,temp,o=1;
     89     freopen("D:\\in.txt","r",stdin);
     90     scanf("%d",&cas);
     91     while(cas--)
     92     {
     93         scanf("%d%d",&n,&m);
     94         for(i=1;i<=n;i++)
     95         {
     96             scanf("%*c");
     97             for(j=1;j<=m;j++)
     98             {
     99                 scanf("%c",&v[i][j]);
    100             }
    101         }
    102         ansR=get_rectange('R');
    103         ansB=get_rectange('B');
    104         for(i=1;i<=m;i++)
    105             v[0][i]='*';
    106         for(i=0;i<=n;i++)
    107             v[i][0]=v[i][m+1]='*';
    108         ansC=DP();
    109         if(ansR>ansC)
    110             ansC=ansR;
    111         if(ansB>ansC)
    112             ansC=ansB;
    113         printf("Case #%d: %d\n",o++,ansC);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    苹果输入手机号变用户的名字
    iOS 关于UITableView的黑科技
    iOS 详解NSObject协议
    iOS 用xib自定义View
    iOS 关于定位你该注意的那些事
    iOS 内存泄漏
    Swift应用案例 2.闭包入门到精通
    Swift应用案例 1.无限轮播
    多库共存-冲突问题
    多库共存-冲突问题
  • 原文地址:https://www.cnblogs.com/ka200812/p/2719567.html
Copyright © 2011-2022 走看看