dp--悬线dp P4147 玉蟾宫

Posted very-beginning

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dp--悬线dp P4147 玉蟾宫相关的知识,希望对你有一定的参考价值。

题目背景

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

题目描述

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

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

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

输入格式

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

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

输出格式

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

集训最后一天的测试题涉及到悬线dp哇,要感谢yxl学长,在学校讲了快1一个点,回家又在QQ上给我讲了一个晚上,今天早上还再讨论qwq。

大体思路就是一共三个数组,表示三个方向: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 }

 

以上是关于dp--悬线dp P4147 玉蟾宫的主要内容,如果未能解决你的问题,请参考以下文章

[DP专题]悬线法

P4147 玉蟾宫

Luogu4147 玉蟾宫

bzoj3039玉蟾宫 悬线法

BZOJ-3039&1057玉蟾宫&棋盘制作 悬线法

bzoj3039 joyoi1939 玉蟾宫 悬线法