https://www.luogu.org/problemnew/show/P1169

第一次听说到这种dp的名称叫做悬线法,听起来好厉害

题意是求一个矩阵内的最大01交错子矩阵,开始想的是dp[2000][2000][2]维护这个位置向上向左扩充的矩阵最大长度之后n²扫一遍,但是写起来发现并不能有效的扩充,也就是状态转移方程很难写出来。

后来发现有一种奥妙重重的方法叫做悬线法,把我原本向左向上扩充的过程改为记录每一个点向左向右向上的最大长度,这些状态很显然可以通过扫一遍的方法求出来,然后对于每一个点,宽度就是l - r + 1,显然对于同一个合法区间内的点,他的left和right是相同的。

用自上而下的方法递推出到N这一行时这个点向上扩充的最大长度之后递推即可。

悬线法对一类限制下求子矩阵的问题很好用。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
inline int read(){int now=;register char c=getchar();for(;!isdigit(c);c=getchar());
for(;isdigit(c);now=now*+c-'',c=getchar());return now;}
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double eps = 1e-;
const int maxn = ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,K;
int Left[maxn][maxn],Right[maxn][maxn],up[maxn][maxn];
int MAP[maxn][maxn];
int main()
{
Sca2(N,M);
for(int i = ; i <= N ; i ++){
for(int j = ; j <= M ; j ++){
Sca(MAP[i][j]);
Left[i][j] = Right[i][j] = j;
up[i][j] = ;
}
}
for(int i = ; i <= N ; i ++){
for(int j = ; j <= M ; j ++){
if(MAP[i][j] != MAP[i][j - ]){
Left[i][j] = Left[i][j - ];
}
}
for(int j = M - ; j >= ; j --){
if(MAP[i][j] != MAP[i][j + ]){
Right[i][j] = Right[i][j + ];
}
}
}
int ans1 = ,ans2 = ;
for(int i = ; i <= N ; i ++){
for(int j = ; j <= M ; j ++){
if(i > && MAP[i][j] != MAP[i - ][j]){
Left[i][j] = max(Left[i][j],Left[i - ][j]);
Right[i][j] = min(Right[i][j],Right[i - ][j]);
up[i][j] = up[i - ][j] + ;
}
int a = Right[i][j] - Left[i][j] + ;
int b = min(a,up[i][j]);
ans1 = max(ans1,b * b);
ans2 = max(ans2,a * up[i][j]);
}
}
Pri(ans1);
Pri(ans2);
return ;
}

[ZJOI2007]棋盘制作 悬线法dp 求限制下的最大子矩阵的更多相关文章

  1. P1169 [ZJOI2007]棋盘制作 && 悬线法

    P1169 [ZJOI2007]棋盘制作 给出一个 \(N * M\) 的 \(01\) 矩阵, 求最大的正方形和最大的矩形交错子矩阵 \(n , m \leq 2000\) 悬线法 悬线法可以求出给 ...

  2. BZOJ 1057: [ZJOI2007]棋盘制作 悬线法求最大子矩阵+dp

    1057: [ZJOI2007]棋盘制作 Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑 ...

  3. P1169 [ZJOI2007]棋盘制作[悬线法/二维dp]

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8 \times 88×8大小的黑白相间的方阵,对应八八六十四卦,黑白 ...

  4. 洛谷P1169 [ZJOI2007]棋盘制作 悬线法 动态规划

    P1169 [ZJOI2007]棋盘制作 (逼着自己做DP 题意: 给定一个包含0,1的矩阵,求出一个面积最大的正方形矩阵和长方形矩阵,要求矩阵中相邻两个的值不同. 思路: 悬线法. 用途: 解决给定 ...

  5. P1169 [ZJOI2007]棋盘制作——悬线法

    ---恢复内容开始--- 给你一个矩阵,选出最大的棋盘,棋盘的要求是黑白相间(01不能相邻),求出最大的正方形和矩形棋盘的面积: 数据n,m<=2000; 这个一看就可能是n2DP,但是写不出. ...

  6. P1169 [ZJOI2007]棋盘制作 悬线法or单调栈

    思路:悬线法\(or\)单调栈 提交:2次 错因:正方形面积取错了\(QwQ\) 题解: 悬线法 讲解:王知昆\(dalao\)的\(PPT\) 详见代码: #include<cstdio> ...

  7. 【ZJOI2007】棋盘制作 - 悬线法

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个 \(8 \times 8\) 大小的黑白相间的方阵,对应八八六十四卦 ...

  8. luogu 1169 [ZJOI2007]棋盘制作 悬线dp

    悬线法,虽然得不到局部最优解,但是一定能得到全局最优解的算法,十分神奇~ #include <cstdio> #include <algorithm> #define N 20 ...

  9. 【BZOJ-3039&1057】玉蟾宫&棋盘制作 悬线法

    3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 753  Solved: 444[Submit][Status][Discuss] D ...

随机推荐

  1. Redis宕机的问题

    在主从模式下宕机要分为区分来看: slave从redis宕机 ​ 在Redis中从库重新启动后会自动加入到主从架构中,自动完成同步数据: ​ 如果从数据库实现了持久化,只要重新假如到主从架构中会实现增 ...

  2. Hibernate中的Entity类之间的继承关系之一MappedSuperclass

    在hibernate中,Entity类可以继承Entity类或非Entity类.但是,关系数据库表之间不存在继承的关系.那么在Entity类之间的继承关系,在数据库表中如何表示呢? Hibernate ...

  3. chrome实用快捷键速记

    标签页和窗口快捷键 操作 快捷键 打开新窗口 Ctrl + n 无痕模式下打开新窗口 Ctrl + Shift + n 打开新的标签页,并跳转到该标签页 Ctrl + t 重新打开最后关闭的标签页,并 ...

  4. VSCode里面HTML添加CSS时没有提示

    看到知乎上的回答,vscode修改设置的: "editor.parameterHints": true, "editor.quickSuggestions": ...

  5. 查询SQL磁盘活动量信息

    /* 用来显示有关由 Transact-SQL 语句生成的磁盘活动量的信息.*/DBCC DROPCLEANBUFFERS --清空缓存set statistics io on --开启set sta ...

  6. 学习Android过程中遇到的问题及解决方法——AS为xutils添加依赖

    在使用xutils时遇到不能添加以来的问题,花了很长时间终于解决,网上添加依赖的方法很多,在此针对个人出现的问题作下笔记. 我本想使用jar包,因为在使用smartImageView时是用的jar包来 ...

  7. [洛谷P2627] 修剪草坪

    传送门:>Here< 题意:不能有连续超过$k$个奶牛的一段,求最大的和 思路分析 Dp还是容易看出来的. 我的第一感觉是一维,$f[i]$表示前i头奶牛的最大效率.其实这也是可以解的,具 ...

  8. 【ARC072E】Alice in linear land DP

    题目大意 有一个人要去直线上\(lm\)远处的地方,他会依次给他的机器发出\(n\)个指令.第\(i\)个指令为\(d_i\).他的机器收到一个指令\(x\)后,如果向目的地方向前进\(xm\)后比当 ...

  9. Android 简单天气预报

    IDE: Android studio3.1.2 界面: activity_main.xml

  10. 【CF833E】Caramel Clouds(线段树)

    [CF833E]Caramel Clouds(线段树) 题面 CF 洛谷 题解 首先把区间一段一段分出来,那么只有四种情况. 要么没有被任何一朵云被覆盖,那么直接就会产生这一段的贡献. 要么被一朵云覆 ...