[HAOI2007]修筑绿化带 题解
作者:互联网
题意分析
给出一个 $m*n$ 的矩阵 $A$ ,要求从中选出一个 $a*b$ 的矩阵 $B$ ,再从矩阵 $B$ 中选出一个 $c*d$ 的矩阵 $C$ ,要求矩阵 $B,C$ 的边界不能重合,求矩阵 $C$ 在矩阵 $B$ 中的补集的权值和的最大值。
思路分析
通过分析题目后可以发现本题可以用二维单调队列进行求解,同时利用到了二维前缀和。即先对其中一维进行求解,然后再求解另一维。
具体实现
1. 预处理二维前缀和
设 $suml_{i,j}$ 表示以 $(i,j)$ 为右下角的矩形 $B$ 的权值和, $sums_{i,j}$ 表示以 $(i,j)$ 为右下角的矩形 $C$ 的权值和,$sum_{i,j}$ 表示 $(i,j)$ 的二维前缀和。递推式显然,就不赘述了。
2. 利用单调队列求解列的答案
设 $f1_{i,j}$ 表示以 $(i,j-b+d+1\sim j-1)$ 为右下角的矩阵 $C$ 中权值和的最大的矩阵,则对于每个 $j$ ,有:
- 从队头排除过时决策
- 若能构成矩阵 $B$ ,即 $j\geq b$,则队头为当前答案
- 从队尾排除无用决策
- 从队尾插入当前决策
3. 利用单调队列求解列的答案
设 $f2_{i,j}$ 表示以 $(i-a+c+1\sim i,j-b+d+1\sim j-1)$ 为右下角的矩阵 $C$ 中权值和的最大的矩阵,求解过程与上步类似,就不赘述了。
4. 遍历一遍找出答案
此时 $suml_{i,j}-f2_{i,j}$ 就是以 $(i,j)$ 为右下角的矩阵 $B$ 的答案,遍历所有矩阵 $B$ ,找出最大值即可。
有一个需要注意的点,矩阵 $B,C$ 的边界不能重合,在递推的时候下标需要注意。举例:$(c,d)$ 不能作为决策和答案,$(c+1,d+1)$ 只能作为决策而不能作为答案。
#include<iostream> #include<cstdio> #include<queue> using namespace std; const int N=1100; int m,n,a,b,c,d,ans; int s[N][N],sum[N][N],suml[N][N],sums[N][N],f1[N][N],f2[N][N]; deque<int> q; int main() { scanf("%d%d%d%d%d%d",&m,&n,&a,&b,&c,&d); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) scanf("%d",&s[i][j]),sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+s[i][j];//递推二维前缀和 for(int i=a;i<=m;i++) for(int j=b;j<=n;j++) suml[i][j]=sum[i][j]-sum[i-a][j]-sum[i][j-b]+sum[i-a][j-b]; for(int i=c+1;i<=m;i++) for(int j=d+1;j<=n;j++) sums[i][j]=sum[i][j]-sum[i-c][j]-sum[i][j-d]+sum[i-c][j-d];//预处理 for(int i=c+1;i<=m;i++) { q.clear();q.push_back(d+1); for(int j=d+2;j<=n;j++) { while(q.size() && q.front()<j-b+d+1) q.pop_front(); if(j>=b) f1[i][j]=sums[i][q.front()]; while(q.size() && sums[i][q.back()]>=sums[i][j]) q.pop_back(); q.push_back(j); } }//求解第一维 for(int j=b;j<=n;j++) { q.clear();q.push_back(c+1); for(int i=c+2;i<=m;i++) { while(q.size() && q.front()<i-a+c+1) q.pop_front(); if(i>=a) f2[i][j]=f1[q.front()][j]; while(q.size() && f1[q.back()][j]>=f1[i][j]) q.pop_back(); q.push_back(i); } }//求解第二维 for(int i=a;i<=m;i++) for(int j=b;j<=n;j++) ans=max(ans,suml[i][j]-f2[i][j]); //找出答案 printf("%d",ans); return 0; }
标签:f1,绿化带,求解,int,题解,d%,矩阵,back,HAOI2007 来源: https://www.cnblogs.com/TEoS/p/13460862.html