[AGC033D] Complexity
链接
题目大意
给定一个 的矩阵。
定义一个矩阵的元素如果全部相等那么他的“混乱度”为0。否则你可以用一条直线将其分为两个子矩阵,混乱度为两个子矩阵的混乱度较大值+1。
题解
首先显然有一个 的dp:令 表示子矩阵的混乱度。每次二分加单调队列得到结果。
但是这样显然过不去,考虑优化。首先这个状态数显然不行。
我们分析最后的答案。可以发现,我们可以每次先按x的中点切,再按y的中点切,这样最坏也是 的。
那么我们不妨枚举这样一个答案作为转移步数。然后令转移状态 表示当前的转移步数下 轴在 中, 轴左端点为 时 轴最右端能到哪里。
考虑转移。对于 轴可以直接套用类似于倍增的思路,即 。 转移。
然后对于 轴,可以发现它的函数 中两个子函数一个单增一个单减。
那么很显然哪边大往哪边靠一定较优,所以符合二分。转移复杂度 。
当然还有 双指针转移。不过这里 也能通过。总复杂度 。
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 210
using namespace std;
char s[N][N];
int f[2][N][N][N];
int main()
{
int n,m,u=1;
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++) scanf("%s",s[i]+1);
for(int j=1;j<=m;j++)
for(int i=j;i;i--)
for(int k=n;k;k--)
if(i==j) f[u][i][j][k]=s[i][k]==s[i][k+1]?f[u][i][j][k+1]:k+1;
else f[u][i][j][k]=s[j-1][k]==s[j][k]?min(f[u][i][j-1][k],f[u][j][j][k]):k;
for(int ans=0;ans<=n;ans++)
{
if(f[u][1][m][1]==n+1){printf("%d\n",ans);return 0;}
int p=u;u=!u;
for(int lf=1;lf<=m;lf++)
for(int rf=lf;rf<=m;rf++)
for(int k=1;k<=n;k++)
{
if(f[p][lf][rf][k]==n+1) f[u][lf][rf][k]=n+1;
else f[u][lf][rf][k]=f[p][lf][rf][f[p][lf][rf][k]];
for(int l=lf,r=rf;l<=r;)
{
int mid=(l+r)>>1;
f[u][lf][rf][k]=max(f[u][lf][rf][k],min(f[p][lf][mid][k],f[p][mid+1][rf][k]));
if(f[p][lf][mid][k]>f[p][mid+1][rf][k]) l=mid+1;
else r=mid-1;
}
}
}
return 0;
}
本文来自博客园,作者:Flying2018,转载请注明原文链接:https://www.cnblogs.com/Flying2018/p/13883370.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理