玉蟾宫 洛谷P4147玉蟾宫
给一个矩阵,一些点有障碍物,求最大子矩阵
做法 悬线法dp,第一次听说。
步骤 (1)结论:答案一定是一个矩形(废话。。。) (2)最大矩形一定是:由其中某个点,先向上扩展到最大,然后再分别向左、向右走到最远。 (3)由于(2)的结论对所有点这样操作,一定可以找到最大矩形 (4) 注意先初始化h,L,R,然后在h=1的时候预处理L,R,然后再更新h,同时更新L,R,并且统计答案
具体代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #include <bits/stdc++.h> using namespace std;const int N=1e3 +5 ;char a[N][N];int n,m;int h[N][N];int L[N][N];int R[N][N];int ans=0 ; int main () { cin>>n>>m; for (int i=1 ;i<=n;i++){ for (int j=1 ;j<=m;j++){ cin>>a[i][j]; if (a[i][j]=='F' )h[i][j]=1 ; L[i][j]=R[i][j]=j; } } for (int i=1 ;i<=n;i++){ for (int j=1 ;j<=m;j++){ if (a[i][j]=='F' &&a[i][j-1 ]=='F' ){ L[i][j]=L[i][j-1 ]; } } for (int j=m;j>=1 ;j--){ if (a[i][j]=='F' &&a[i][j+1 ]=='F' ){ R[i][j]=R[i][j+1 ]; } } } for (int i=1 ;i<=n;i++){ for (int j=1 ;j<=m;j++){ if (a[i][j]=='F' &&a[i-1 ][j]=='F' ){ h[i][j]=h[i-1 ][j]+1 ; L[i][j]=max (L[i][j],L[i-1 ][j]); R[i][j]=min (R[i][j],R[i-1 ][j]); } if (a[i][j]=='F' ){ ans=max (ans,h[i][j]*(R[i][j]-L[i][j]+1 )); } } } cout<<ans*3 <<endl; return 0 ; }
ICPC银川 Largest Common Submatrix
给定一个矩阵A和一个矩阵B,求最大子矩阵,满足最大子矩阵同时是A的最大子矩阵和B的最大子矩阵
做法 悬线法dp,注意转移条件,以及边界问题!!!
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 #include <bits/stdc++.h> using namespace std;const int N=1e3 +5 ;int a[N][N];int b[N][N];int n,m;int h[N][N];int L[N][N];int R[N][N]; pair<int ,int >pos[N*N];int ans=0 ;int main () { ios::sync_with_stdio (0 ), cin.tie (0 ), cout.tie (0 ); cin>>n>>m; for (int i=1 ; i<=n; i++) { for (int j=1 ; j<=m; j++) { cin>>a[i][j]; h[i][j]=1 ; L[i][j]=R[i][j]=j; } } for (int i=1 ; i<=n; i++) { for (int j=1 ; j<=m; j++) { cin>>b[i][j]; pos[b[i][j]]= {i,j}; } } for (int i=1 ; i<=n; i++) { for (int j=2 ; j<=m; j++) { int x=a[i][j]; int y=a[i][j-1 ]; int bx=pos[x].first; int by=pos[x].second; if (b[bx][by-1 ]==y) { L[i][j]=L[i][j-1 ]; } } for (int j=m-1 ; j>=1 ; j--) { int x=a[i][j]; int y=a[i][j+1 ]; int bx=pos[x].first; int by=pos[x].second; if (b[bx][by+1 ]==y) { R[i][j]=R[i][j+1 ]; } } } int ans=0 ; for (int i=1 ; i<=n; i++) { for (int j=1 ; j<=m; j++) { int x=a[i][j]; int y=a[i-1 ][j]; int bx=pos[a[i][j]].first; int by=pos[a[i][j]].second; if (y&&b[bx-1 ][by]==y) { h[i][j]=h[i-1 ][j]+1 ; L[i][j]=max (L[i][j],L[i-1 ][j]); R[i][j]=min (R[i][j],R[i-1 ][j]); } ans=max (ans,h[i][j]*(R[i][j]-L[i][j]+1 )); } } cout<<ans<<endl; return 0 ; }