题意

给出一个\(n*m\)的\(0,1\)矩阵,若一个矩阵中的所有元素都相同,则这个矩阵的代价为\(0\),如果不是则选择一种将它分成两个子矩阵的方案,代价为所有方案中(两个子矩阵的代价的较大值+\(1\))的最小值。

\(n,m \leq 185\)

传送门

思路

\(dp[ i ][ j ][ k ][ l ]\) 表示左上角是 $( i , j ) $ 、右下角是 $ ( k , l ) $的矩阵的最小代价,四维扛不住。

因为如果每次从中间分,\(log(n)+log(m)\)次就变成\(1*1\)的格子,代价是 \(0\),所以答案最多是\(log(n)+log(m)\)。

因此可以将值放进状态中,$dp[ i ][ j1 ][ j2 ][ k ] $表示左上角是 \(( i , j1 )\)、右上角是 $ ( i , j2 ) $ 、用$ k $的代价,往下最长能延伸到哪行。

转移的时候考虑横着切与竖着切。令$ d = dp[ i ][ j1 ][ j2 ][ k ]$ :

  • 横着切:$ d = dp \space [ dp[ i ][ j1 ][ j2 ][ k-1 ] +1] \space [ j1 ][ j2 ][ k-1 ] $;

  • 竖着切:\([ j1 , j3 ] 和 [ j3+1 , j2 ]\) 就是分出的两部分;

    \(dp[ i ][ j1 ][ j3 ][ k-1 ]\) 和 \(dp[ i ][ j3+1 ][ j2 ][ k-1 ]\)的最小值是答案,\(d\)为最小值中的最大值。至此我们得出了\(O(m)\)的暴力转移。

    因为\(dp\)值明显随矩阵增大而减小,所以可二分\(j3\)。考虑二分找出最大的\(min( dp[ i ][ j1 ][ j3 ][ k-1 ] , dp[ i ][ j3+1 ][ j2 ][ k-1 ] )\)。(左比右大往左,反过来,总之越接近越好)

初始化出所有\(k=0\)的情况即可

#include <bits/stdc++.h>
const int N=190;
using std::max;
using std::min;
int n,m,a[N][N],sum[N][N],dp[N][N][N][15];
char c[N][N];
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%s",c[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if (c[i][j]=='.') a[i][j]=1;
else a[i][j]=0;
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
for (int k=j;k<=m;k++){
int l=i,r=n,ans=i-1;
while (l<=r){
int mid=(l+r)>>1;
int s=sum[mid][k]-sum[mid][j-1]-sum[i-1][k]+sum[i-1][j-1];
if (s==0 || s==(mid-i+1)*(k-j+1))
ans=mid,l=mid+1;
else r=mid-1;
}
dp[i][j][k][0]=ans;
}
int k=1;
for (k=1;dp[1][1][m][k-1]<n;k++)
for (int h=1;h<=m;h++)
for (int i=1;i<=n;i++)
for (int j1=1,j2=j1+h-1;j2<=m;j1++,j2++){
if (dp[i][j1][j2][k-1]==n){
dp[i][j1][j2][k]=n;
continue;
}
dp[i][j1][j2][k]=dp[dp[i][j1][j2][k-1]+1][j1][j2][k-1];//横
if(dp[i][j1][j2][k]==n) continue;
int l=j1,r=j2-1,ans=0;//竖
while (l<=r){
int mid=(l+r)>>1;
int x=dp[i][j1][mid][k-1],y=dp[i][mid+1][j2][k-1];
ans=max(ans,min(x,y));
if (x<y) r=mid-1;
else l=mid+1;
} dp[i][j1][j2][k]=max(dp[i][j1][j2][k],ans);
}
printf("%d\n",k-1);
}

AGC033D Complexity的更多相关文章

  1. DP 优化小技巧

    收录一些比较冷门的 DP 优化方法. 1. 树上依赖性背包 树上依赖性背包形如在树上选出若干个物品做背包问题,满足这些物品连通.由于 01 背包,多重背包和完全背包均可以在 \(\mathcal{O} ...

  2. Instant Complexity - POJ1472

    Instant Complexity Time Limit: 1000MS Memory Limit: 10000K Description Analyzing the run-time comple ...

  3. Runtime Complexity of .NET Generic Collection

    Runtime Complexity of .NET Generic Collection   I had to implement some data structures for my compu ...

  4. Examples of complexity pattern

    O(1):constant - the operation doesn't depend on the size of its input, e.g. adding a node to the tai ...

  5. 空间复杂度是什么?What does ‘Space Complexity’ mean? ------geeksforgeeks 翻译

    这一章比较短! 空间复杂度(space complexity)和辅助空间(auxiliary space)经常混用,下面是正确的辅助空间和空间复杂度的定义 辅助空间:算法需要用到的额外或者暂时的存储空 ...

  6. 三部曲二(基本算法、动态规划、搜索)-1004-Instant Complexity

    Instant Complexity Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other) ...

  7. THE ARCHITECTURE OF COMPLEXITY HERBERT A. SIMON* Professor of Administration, Carnegie Institute of Technology (Read April 26, 1962)

    THE ARCHITECTURE OF COMPLEXITY HERBERT A. SIMON* Professor of Administration, Carnegie Institute of ...

  8. CLRS:master theory in complexity of algorithm

    T(n)=aT(n/b)+f(n); where we can interpret n/b to mean either floor(b/n) or ceil(b/n), Then T (n) has ...

  9. The Brain vs Deep Learning Part I: Computational Complexity — Or Why the Singularity Is Nowhere Near

    The Brain vs Deep Learning Part I: Computational Complexity — Or Why the Singularity Is Nowhere Near ...

随机推荐

  1. winfrom_关于打印小票

    1.使用的是PrintDocument控件,在工具箱  ,将其托到窗体上: 2. private void btnprint_Click(object sender, EventArgs e) { p ...

  2. luogu4302字符串折叠题解--区间DP

    题目链接 https://www.luogu.org/problemnew/show/P4302 分析 很明显一道区间DP题,对于区间\([l,r]\)的字符串,如果它的字串是最优折叠的,那么它的最优 ...

  3. Android应用市场App发布

    来自知乎 Android应用市场App发布说到官方渠道,不得不说一些主要的大市场了,如:360.小米.应用宝.91.安卓.百度.豌豆荚.安智.现在我来一一说它们的一些简单特点. 1,360 (1)当天 ...

  4. java 日期。时间

    友情链接: https://www.cnblogs.com/wanson/articles/10818955.html

  5. idea启动卡死,项目界面一直processing

    1 原因 因为上次退出项目,非正常退出,导致索引生成有问题. 2 解决办法 删除项目根目录下 .idea文件夹,然后重新打开,重新indexing生成索引文件

  6. Linux基础篇之FTP服务器搭建(二)

    上一篇文章说到了搭建FTP匿名用户的访问,接下来讲解一下本地用户的登录. 一.首先先建立一个用户,这里举例:xiaoming,并为其设置密码.  二.修改配置文件. 文件:ftpusers 文件:us ...

  7. C#DataGrid列值出现E形式的小数,将DataGrid表格上的数据保存至数据库表时会因格式转换不正确导致报错

    问题描述:在DataGridView中调整金额一列,当输入小数0.000001后会显示1E-6,此时进行保存操作时报错,提示无法将string类型转换成Decimal 原因分析:由于列调整金额为1E- ...

  8. Mybatis入门配置及第一个Mybatis程序

    目的:使用mybatis来进行对数据库表的操作 第一步:引入jar包 我这里是创建的maven工程 第二步:创建数据表user 第三步:创建实体类 实体类放在包 com.xxx.pojo 下,包名可自 ...

  9. PAT Basic 1064 朋友数 (20 分)

    如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”.例如 123 和 51 就是朋友数,因为 1+2+3 = 5+1 = 6,而 6 就是它们的朋友证号.给定 ...

  10. PAT Basic 1061 判断题 (15 分)

    判断题的评判很简单,本题就要求你写个简单的程序帮助老师判题并统计学生们判断题的得分. 输入格式: 输入在第一行给出两个不超过 100 的正整数 N 和 M,分别是学生人数和判断题数量.第二行给出 M ...