dp--悬线dp P4147 玉蟾宫

题目背景

有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。

题目描述

这片土地被分成$N\times M$个格子,每个格子里写着'$R$'或者'$F$',$R$代表这块土地被赐予了$rainbow$,F代表这块土地被赐予了$freda$。

现在$freda$要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着'$F$'并且面积最大。

但是$rainbow$和$freda$的$OI$水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为$S$,它们每人给你S两银子。

输入格式

第一行两个整数$N$,$M$,表示矩形土地有$N$行$M$列。

接下来$N$行,每行$M$个用空格隔开的字符'$F$'或'$R$',描述了矩形土地。

输出格式

输出一个整数,表示你能得到多少银子,即(43\times$最大'$F$'矩形土地面积)的值。

 

大体思路就是一共三个数组,表示三个方向:$r[i][j]$表示当前位置能向右拓展的最远位置,$l[i][j]$表示当前位置能向左拓展的最远位置,$up[i][j]$表示当前位置能向上拓展的最远位置。由于“木桶效应”,我们所能围城的最大矩形的面积其实也取决于最短的一个长度,$r-l+1$就是矩形的长,$i-up$就是矩形的高,长和高都知道了的话,矩形的面积就很好求了吧,说的可能比较简略。

代码如下:

 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 int n,m;
 5 int a[2000][2000]; 
 6 char c;
 7 int l[2000][2000];
 8 int r[2000][2000];
 9 int up[2000][2000];
10 int main()
11 {
12     scanf ("%d%d",&n,&m);
13     for (int i = 1;i <= n;i++)
14     {
15         for (int j =1;j<= m;j++)
16         {
17             cin>>c;
18             if (c=='F')
19                 a[i][j]=1; 
20             l[i][j]=j;
21             r[i][j]=j;
22             up[i][j]=i; 
23         }
24     }
25     for (int i = 1;i <= n;i++)
26     {
27         for (int j = 2;j <= m;j++)
28         {
29             if (!a[i][j]^a[i][j-1]&&a[i][j]==1)
30                 l[i][j]=l[i][j-1];
31         }
32     }    
33     for (int i = 1;i <= n;i++)
34     {
35         for (int j = m-1;j >= 1;j--)
36         {
37             if (!a[i][j]^a[i][j+1]&&a[i][j]==1)
38                 r[i][j]=r[i][j+1];
39         }
40     }    
41     for (int i = 2;i <= n;i++)
42     {
43         for (int j = 1;j <= m;j++)
44         {
45         
46             if (!a[i-1][j]^a[i][j]&&a[i][j]==1)
47                 up[i][j]=up[i-1][j],l[i][j]=max(l[i-1][j],l[i][j]),r[i][j]=min(r[i-1][j],r[i][j]);
48         }
49     }    
50     int ans=0;
51     int tmp;
52     for (int i = 1;i <= n;i++)
53     {
54         for (int j = 1;j <= m;j++)
55         {
56             if (a[i][j]==1)
57             {
58             tmp = r[i][j]-l[i][j]+1;
59              ans=max(ans,tmp*(i-up[i][j]+1));
60         }
61         }
62     }
63     cout<<ans*3<<endl;
64     return 0;
65 }

 

posted @ 2020-01-22 12:57  小又又  阅读(177)  评论(0编辑  收藏  举报