P1169 [ZJOI2007] 棋盘制作
链接
https://www.luogu.com.cn/problem/P1169
思路
刚开始想用类似深搜的方法:搜到一个块,然后用扫描线。 结果感觉太麻烦(而且没有用到标签的dp),看了下题解用的是悬线法
(和扫描线也差不多嘛)。
大概的思路就是通过计算一个点向左最多能达到多远,向右最多能达到多远,向上最多能达到多远来计算。关键的公式:
这其实是预处理,然后通过从上往下进行dp就行了
代码
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
const int N = 2e3 + 10;
int mp[N][N];
int n, m;
int lef[N][N], rig[N][N], up[N][N];
signed main()
{
IOS;
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> mp[i][j];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
lef[i][j] = rig[i][j] = j;
for(int i=1;i<=n;i++)
for (int j = 2; j <= m; j++)
if(mp[i][j]!=mp[i][j-1])
lef[i][j] = min(lef[i][j], lef[i][j - 1]);
for (int i = 1; i <= n; i++)
for (int j = m - 1; j >= 1; j--)
if (mp[i][j] != mp[i][j + 1])
rig[i][j] = max(rig[i][j], rig[i][j + 1]);
int matrixS = 1, squareS = 1;
for (int j = 1; j <= m; j++)
{
up[1][j] = 1;
matrixS = max(matrixS, (rig[1][j] - lef[1][j]+1));
}
for (int i = 2; i <= n; i++)
for (int j = 1; j <= m; j++)
{
if (mp[i][j] != mp[i - 1][j])
{
up[i][j] = up[i - 1][j] + 1;
lef[i][j] = max(lef[i - 1][j], lef[i][j]);
rig[i][j] = min(rig[i][j], rig[i - 1][j]);
}
else up[i][j] = 1;
matrixS = max(matrixS, (rig[i][j] - lef[i][j]+1) * up[i][j]);
squareS = max(squareS, (int)pow(min(rig[i][j] - lef[i][j]+1, up[i][j]), 2));
}
cout << squareS << '\n' << matrixS;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】