UVa LA 3029 City Game 状态拆分,最大子矩阵O(n2) 难度:2
题目
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1030
题意
矩阵,有障碍和普通地面两种子元素,求普通地面连成的子矩阵面积最大值 * 3
思路
如刘书
对于子矩阵长方形来说,其底边上必然有一点,该点向上可以延伸的距离就是子矩阵的长,枚举这一点,设为(i,j)。(i,j)不是障碍是普通地面。
令up[i][j]为其向上能延伸的距离,llen[i][j]为以up[i][j]为长的长方形,左边最早开始于哪里,rlen[i][j]为依此右边最晚结束于哪里。
up[i][j]=(i?up[i - 1][j] + 1)
但要如何更新llen和rlen呢?
考虑上方(i - 1, j),如果(i - 1, j)是障碍,那么up[i][j] = 1, llen[i][j]就是(i, j)左边的障碍横坐标+1,rlen以此类推。
如果(i- 1, j)不是障碍,第一种情况,llen[i][j] = llen[i - 1][j],在这多填出的一层内没有障碍物,另一种情况,llen[i][j]依然是(i, j)左边的障碍横坐标+1。
rlen以此类推。
感想
1. 一开始没有想到枚举(i,j)这根作为面积的长,而只是想到枚举(i,j)作为右下角。这样就还要用费时间的方式确定此时的面积长。
2. 后来没想到可以用上方而不是左方来更新rlen或者llen。没有意识到如果上方是障碍,那么只要看左/右的障碍在哪里即可。
3. 最后本来用的是(i && maze[i - 1][j] != 'R'),不知道哪里错了
代码
- #include <algorithm>
- #include <cassert>
- #include <cmath>
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <map>
- #include <queue>
- #include <set>
- #include <tuple>
- #define LOCAL_DEBUG
- using namespace std;
- const int MAXN = 1e3 + ;
- char maze[MAXN][MAXN];
- int up[MAXN][MAXN];
- int llen[MAXN][MAXN];
- int rlen[MAXN][MAXN];
- int main() {
- #ifdef LOCAL_DEBUG
- freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\input.txt", "r", stdin);
- //freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\output.txt", "w", stdout);
- #endif // LOCAL_DEBUG
- int T;
- scanf("%d", &T);
- for (int ti = ; ti <= T; ti++) {
- int n, m;
- scanf("%d%d", &n, &m);
- for (int i = ; i < n; i++) {
- for (int j = ; j < m; j++) {
- char tmp[];
- scanf("%s", tmp);
- maze[i][j] = tmp[];
- }
- }
- for (int i = ; i < n; i++) {
- for (int j = , last_impede=-; j < m; j++) {
- if (maze[i][j] == 'R') {
- up[i][j] = ;
- llen[i][j] = ;
- last_impede = j;
- }
- else {
- up[i][j] = (i ? up[i - ][j] : ) + ;
- llen[i][j] = max((i ? llen[i - ][j] : ), last_impede + );
- }
- }
- }
- int ans = ;
- for (int i = ; i < n; i++) {
- for (int j = m - , last_impede = m; j >= ; j--) {
- if (maze[i][j] == 'R') {
- rlen[i][j] = m;
- last_impede = j;
- }
- else {
- rlen[i][j] = min((i ? rlen[i - ][j] : m), last_impede - );
- ans = max(ans, up[i][j] * (rlen[i][j] - llen[i][j] + ));
- }
- }
- }
- printf("%d\n", ans * );
- }
- return ;
- }
UVa LA 3029 City Game 状态拆分,最大子矩阵O(n2) 难度:2的更多相关文章
- LA 3029 City Game
LA 3029 求最大子矩阵问题,主要考虑枚举方法,直接枚举肯定是不行的,因为一个大矩阵的子矩阵个数是指数级的,因此应该考虑先进行枚举前的扫描工作. 使用left,right,up数组分别记录从i,j ...
- LA 3029 - City Game (简单扫描线)
题目链接 题意:给一个m*n的矩阵, 其中一些格子是空地(F), 其他是障碍(R).找一个全部由F 组成的面积最大的子矩阵, 输出其面积乘以3的结果. 思路:如果用枚举的方法,时间复杂度是O(m^2 ...
- UVA LA 7146 2014上海亚洲赛(贪心)
option=com_onlinejudge&Itemid=8&page=show_problem&category=648&problem=5158&mosm ...
- LA 3029 Subsequence
LA 3029 A sequence of N positive integers (10 < N < 100 000), each of them less than or equal ...
- UVa LA 3695 - Distant Galaxy 前缀和,状态拆分,动态规划 难度: 2
题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- UVa LA 2965 - Jurassic Remains 中间相遇,状态简化 难度: 2
题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- Uva LA 3177 - Beijing Guards 贪心,特例分析,判断器+二分,记录区间内状态数目来染色 难度: 3
题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- .Uva&LA部分题目代码
1.LA 5694 Adding New Machine 关键词:数据结构,线段树,扫描线(FIFO) #include <algorithm> #include <cstdio&g ...
- uva 11195 Another queen (用状态压缩解决N后问题)
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
随机推荐
- HTML5语义化
转载自:https://www.cnblogs.com/fliu/articles/5244866.html 1.什么是HTML语义化? 用合理.正确的标签来展示内容,比如h1~h6定义标题,便于开发 ...
- AtCoder Regular Contest 102 D - All Your Paths are Different Lengths
D - All Your Paths are Different Lengths 思路: 二进制构造 首先找到最大的t,使得2^t <= l 然后我们就能构造一种方法使得正好存在 0 到 2^t ...
- docker 安装完mysql 后客户端无法访问
1.在虚拟机的centos 中安装 docker 的mysql 镜像. docker run --name mysql01 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=12 ...
- Can't push you anymore...
为什么我们不趁着年轻去冒险? 等我们准备好,也许都已经被生活冲淡了激情. Go to different places,to meet different people. To try, to fin ...
- C语言流控制命令的总结
C语言流控制命令的总结 基本概念: C语言中,自顶向下的的代码的流程叫做程序流. 能够改变程序流顺序的语句叫做流控制命令. 我为什么要写这篇文章 在学习C语言的过程中,经常会用到条件语句和循环语句这些 ...
- 雷林鹏分享:C# 判断
C# 判断 判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的). 下面是大多数编程语言中典型的判断结构的一般形式: 判断语句 C ...
- 【模板/经典题型】FWT
FWT在三种位运算下都满足FWT(a×b)=FWT(a)*FWT(b) 其中or卷积和and卷积还可以通过FMT实现(本质上就是个高维前缀和) #include<bits/stdc++.h> ...
- 『MXNet』第四弹_Gluon自定义层
一.不含参数层 通过继承Block自定义了一个将输入减掉均值的层:CenteredLayer类,并将层的计算放在forward函数里, from mxnet import nd, gluon from ...
- 『MXNet』第三弹_Gluon模型参数
MXNet中含有init包,它包含了多种模型初始化方法. from mxnet import init, nd from mxnet.gluon import nn net = nn.Sequenti ...
- loj#2353. 「NOI2007」 货币兑换 斜率优化
题意略 题解:可以列出dp方程\(dp[i]=max(dp[j]*{\frac{a[i]*c[j]+b[i]}{a[j]*c[j]+b[j]}}\),化简可以得到\(\frac{dp[i]}{b[i] ...