P7741 [AHOI2007] 石块地板
FBI Warning
此题是一道思维题,请不要"对着题解调试程序"(大雾
前置芝士
一维前缀和(就够了)
最大子段和(P1115)
二维数组(能做到蓝题的应该都会吧)
思路
注意,这题的
这题明显是一个卡了我两天的最大子矩阵和板子题。
有同学就要问了:那为什么是“和”呢?问的是“差最大”啊?
但是这个“差最大”问题也可以转换成“和最大”问题。
黑(的数目) - 白(的数目)最大,即要求黑尽可能多,白尽可能少。
令黑色表示
反过来,只要所有
所以保证矩阵内的
是不是恍然大明白?(我猜你没有
那么怎么找出这个“和最大”的子矩阵呢?枚举,但不是直接暴力。
首先,在矩阵上划定一个范围:
枚举这个范围需要
将这个范围中每行的和算出来:
每行的和需要
那么,这个范围就被抽象成了灰框内的数组。
算这个数组的最大子段和,最大的子段就对应着最大的矩阵。
这样,最大矩阵就找到了,复杂度
代码
#include <iostream>
#define qjh(r, x, y) s[r][y] - s[r][x - 1]
using namespace std;
int s[401][401], t[401], m, n, ans;char c;
void get()
{
for(int i = 1;i <= m;++i)
{
t[i] = max(t[i], t[i] + t[i - 1]);
ans = max(ans, t[i]);
}
}
int main()
{
cin >> m >> n;
for(int i = 1;i <= m;++i)
for(int j = 1;j <= n;++j)
{
cin >> c;
if(c == '1') s[i][j] = s[i][j - 1] + 1;
if(c == '0') s[i][j] = s[i][j - 1] - 1;
}
for(int i = 1;i <= n;++i)
for(int j = i;j <= n;++j)
{
for(int k = 1;k <= m;++k)
t[k] = qjh(k, i, j);
get();
}
cout << ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具