2023.3.7
其实是 3.4 那天的模拟赛,那天打的挺崩溃来着,但是后来停电了(就很乐),于是比赛没打完,然后一直没来电就提前放学了捏。今天重赛了,来写写。
T1 洛谷:P1169 [ZJOI2007]棋盘制作
参考了洛谷大佬的题解。tql。
思路:找到符合 0101 这样的最大长方形和正方形。垂线法 dp:记录每个格子 (i, j) 最右端的障碍点、最左端的障碍点、上下能拓展的长度,即垂线标注,分别用 l[i][j],r[i][j],up[i][j] 表示。
1.初始化:从列的角度根据之前的分别初始记录障碍点,注意边界。
2.一边计算一边更新:从行的角度根据之前的分别更新障碍点。up 向下拓展。
方程 : l[i][j] = max(l[i][j], l[i - 1][j]), r[i][j] = min(r[i][j], r[i - 1][j]), up[i][j] = up[i - 1][j] + 1。
至于为什么是 max l 和 min r,可以画图理解,这个就是之前在列处理时,有的地方并没有考虑到行的状态,所以更新准确的障碍点位置。
3.一些脑残的小问题捏:注意区分长和宽;特别注意最后输出时是换行还是空格,有的 sb 题(例如本题)会卡,还是严谨一些好。
#include<bits/stdc++.h>
using namespace std;
const int N = 2010;
int n, m;
int x, y, ans1 = 0, ans2 = 0;
int a[N][N], l[N][N], r[N][N], up[N][N];
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++ )
for(int j = 1; j <= m; j ++ )
{
scanf("%d", &a[i][j]);
l[i][j] = r[i][j] = j;
up[i][j] = 1;
}
for(int i = 1; i <= n; i ++ )
for(int j = 2; j <= m; j ++ )
if(a[i][j] != a[i][j - 1])
l[i][j] = l[i][j - 1];
for(int i = 1; i <= n; i ++ )
for(int j = m - 1; j >= 1; j -- )
if(a[i][j] != a[i][j + 1])
r[i][j] = r[i][j + 1];
for(int i = 1; i <= n; i ++ )
for(int j = 1; j <= m; j ++ )
{
if(i > 1 && a[i][j] != a[i - 1][j])
{
l[i][j] = max(l[i][j], l[i - 1][j]);
r[i][j] = min(r[i][j], r[i - 1][j]);
up[i][j] = up[i - 1][j] + 1;
}
x = r[i][j] - l[i][j] + 1;
y = min(up[i][j], x);
ans1 = max(ans1, y * y);
ans2 = max(ans2, x * up[i][j]);
}
printf("%d\n%d", ans1, ans2);
return 0;
}
T2 bzoj 2086 Blocks
由于 bzoj 好像很久之前就寄了,所以这里光放一下题面捏。
本题正解:dp + 单调栈(甚至不算 dp )。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 10;
int n, m;
ll k;
ll a[N], sum[N];
int sta[N], top = 0;
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
while(m -- )
{
scanf("%lld", &k);
int ans = 0;
top = 0;
for(int i = 1; i <= n; i ++ ) {
sum[i] = sum[i - 1] + a[i] - k;
if(sum[i] < sum[sta[top]]) sta[++ top] = i;
}
sta[top + 1] = N;
for(int i = n; i >= 1; i -- ) {
while(top && sum[i] - sum[sta[top - 1]] >= 0) top--;
ans = max(ans, i - sta[top]);
}
printf("%d\n", ans);
}
return 0;
}