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 玉蟾宫的主要内容,如果未能解决你的问题,请参考以下文章