题目请戳这里

题目大意:给一个H行W列的01矩阵,求最少用多少个正方形框住所有的1.

题目分析:又是一个红果果的重复覆盖模型.DLX搞之!

枚举矩阵所有的子正方形,全1的话建图.判断全1的时候,用了一个递推,dp[i][j][w][h]表示左上角(i,j)的位置开始长h宽w的矩形中1的个数,这样后面可以迅速判断某个正方形是否全1.

不过此题直接搜一直TLE,然后改成迭代加深就比较愉快啦

详情请见代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int N = 11;
const int M = 50005;
int dp[N][N][N][N];
int n,m,num,ans;
int mp[N][N];
bool vis[105];
int s[M],h[M],col[M],u[M],d[M],l[M],r[M]; void init()
{
memset(h,0,sizeof(h));
memset(s,0,sizeof(s));
int i,c;
c = m * n;
for(i = 0;i <= c;i ++)
{
u[i] = d[i] = i;
l[i] = (i + c)%(c + 1);
r[i] = (i + 1)%(c + 1);
}
num = c + 1;
} void ins(int i,int j)
{
if(h[i])
{
r[num] = h[i];
l[num] = l[h[i]];
r[l[num]] = l[r[num]] = num;
}
else
h[i] = l[num] = r[num] = num;
s[j] ++;
u[num] = u[j];
d[num] = j;
d[u[num]] = num;
u[j] = num;
col[num] = j;
num ++;
}
void del(int c)
{
for(int i = u[c];i != c;i = u[i])
l[r[i]] = l[i],r[l[i]] = r[i];
}
void resume(int c)
{
for(int i = d[c];i != c;i = d[i])
l[r[i]] = r[l[i]] = i;
} int A()
{
int i,j,k,ret;
ret = 0;
memset(vis,false,sizeof(vis));
for(i = r[0];i;i = r[i])
{
if(vis[i] == false)
{
ret ++;
vis[i] = true;
for(j = d[i];j != i;j = d[j])
for(k = r[j];k != j;k = r[k])
vis[col[k]] = true;
}
}
return ret;
} bool dfs(int k,int lim)
{
if(k + A() > lim)
return false;
if(!r[0])
{
// ans = min(ans,k);
return true;
}
int i,j,c,mn = M;
for(i = r[0];i;i = r[i])
{
if(s[i] < mn)
{
mn = s[i];
c = i;
}
}
for(i = d[c];i != c;i = d[i])
{
del(i);
for(j = l[i];j != i;j = l[j])
del(j);
if(dfs(k + 1,lim)) return true;
for(j = r[i];j != i;j = r[j])
resume(j);
resume(i);
}
return false;
} bool canfuck(int x,int y,int z)
{
return dp[x][y][z][z] == z * z;
int i,j;
for(i = x;i <= x + z - 1;i ++)
for(j = y;j <= y + z - 1;j ++)
if(mp[i][j] == 0)
return false;
return true;
} void fuckba(int x,int y,int z,int id)
{
int i,j;
for(i = x;i <= x + z - 1;i ++)
for(j = y;j <= y + z - 1;j ++)
ins(id,(i - 1) * m + j);
}
void build()
{
int i,j,k;
memset(dp,0,sizeof(dp));
for(i = 1;i <= n;i ++)
for(j = 1;j <= m;j ++)
scanf("%d",&mp[i][j]),dp[i][j][1][1] = mp[i][j];
for(int ii = 1;ii <= n;ii ++)
for(int jj = 1;jj <= m;jj ++)
{
for(i = 1;i + ii <= n + 1;i ++)
{
for(j = 1;j + jj <= 1 + m;j ++)
{
dp[i][j][ii][jj] = dp[i][j][ii - 1][jj - 1] + dp[i + ii - 1][j][1][jj - 1] + dp[i][j + jj - 1][ii - 1][1] + dp[i + ii - 1][j + jj - 1][1][1];
}
}
}
init();
int rownum = 1;
for(k = 1;k <= min(n,m);k ++)//枚举边长
{
for(i = 1;i <= n - k + 1;i ++)
{
for(j = 1;j <= m - k + 1;j ++)
{
if(canfuck(i,j,k))
fuckba(i,j,k,rownum);
rownum ++;
}
}
}
for(i = 1;i <= n * m;i ++)
if(s[i] == 0)
l[r[i]] = l[i],r[l[i]] = r[i];
}
void fuck()
{
// ans = M;TLE....
// dfs(0);
// printf("%d\n",ans);
ans = 0;
while(!dfs(0,ans ++));
printf("%d\n",ans - 1);
}
int main()
{
while(scanf("%d%d",&m,&n),(m + n))
{
build();
fuck();
}
return 0;
}

poj2032Square Carpets(IDA* + dancing links)的更多相关文章

  1. Dancing Links and Exact Cover

    1. Exact Cover Problem DLX是用来解决精确覆盖问题行之有效的算法. 在讲解DLX之前,我们先了解一下什么是精确覆盖问题(Exact Cover Problem)? 1.1 Po ...

  2. 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题

    精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...

  3. ZOJ 3209 Treasure Map (Dancing Links)

    Treasure Map Time Limit: 2 Seconds      Memory Limit: 32768 KB Your boss once had got many copies of ...

  4. HUST 1017 - Exact cover (Dancing Links 模板题)

    1017 - Exact cover 时间限制:15秒 内存限制:128兆 自定评测 5584 次提交 2975 次通过 题目描述 There is an N*M matrix with only 0 ...

  5. Dancing Links初学记

    记得原来备战OI的时候,WCX大神就研究过Dancing Links算法并写了一篇blog.后来我还写了个搜索策略的小文章( http://www.cnblogs.com/pdev/p/3952279 ...

  6. Dancing Links

    Dancing Links用来解决如下精确匹配的问题: 选择若干行使得每一列恰好有一个1.Dancing Links通过对非零元素建立双向十字循环链表.上面的例子建立的链表如下所示: 计算的时候使用搜 ...

  7. 【转】Dancing Links题集

    转自:http://blog.csdn.net/shahdza/article/details/7986037 POJ3740 Easy Finding [精确覆盖基础题]HUST1017 Exact ...

  8. 【转】Dancing Links精确覆盖问题

    原文链接:http://sqybi.com/works/dlxcn/ (只转载过来一部分,全文请看原文,感觉讲得很好~)正文    精确覆盖问题    解决精确覆盖问题    舞蹈步骤    效率分析 ...

  9. POJ 3074 Sudoku (Dancing Links)

    传送门:http://poj.org/problem?id=3074 DLX 数独的9*9的模板题. 具体建模详见下面这篇论文.其中9*9的数独怎么转化到精确覆盖问题,以及相关矩阵行列的定义都在下文中 ...

随机推荐

  1. jquery插件tab——小试牛刀

    <html> <head> <script type="text/javascript" src="http://ajax.googleap ...

  2. Ubuntu下屏幕录像、后期处理不完全攻略

    提要 如果要做成果展示或者效果演示,通常需要录取屏幕生成视频文件,在windows中我们可以用屏幕录像专家在录像, vegas 来做后期处理,Ubuntu可以么? 答案时当然可以!虽然第一次用觉得有点 ...

  3. 显示标题栏中标题左侧的小图icon

    如何显示网站logo,定义网站收藏夹图标 代码与解释 <link rel="shortcut icon" href="/path/favicon.ico" ...

  4. 关于K-Means算法

    在数据挖掘中,K-Means算法是一种cluster analysis的算法,其主要是来计算数据聚集的算法,主要通过不断地取离种子点最近均值的算法. 问题 K-Means算法主要解决的问题如下图所示. ...

  5. 使用 UML 进行业务建模:理解业务用例与系统用例的相似和不同之处

    使用 UML 进行业务建模:理解业务用例与系统用例的相似和不同之处   作者:Arthur V. English 出处:IBM   本文内容包括: 背景 业务用例模型与系统用例模型有什么相似之处? 业 ...

  6. TinyFox 部署在CentOS7 中测试使用

    一:TinyFox介绍 TinyFox 是一款支持OWIN标准的WEB应用的高性能的HTTP服务器,是Jexus Web Server的"姊妹篇".TinyFox本身的功能是htm ...

  7. JSP page include taglib

    page include taglib 语法:<%@ 指令名称 属性=值 属性=值 -%> ------------------- page 1.language 默认值java 2.ex ...

  8. [暂停一天]从零开始PHP学习 - 第六天

    今天这个系列没有时间去写了 在公司完善一个项目     已经备好6瓶咖啡 两天 + 一夜 完成这个项目  真是苦逼 诶 反正这几天 明白一个道理:别以为你多牛B 你不会的东西多了!  比你牛B的人也多 ...

  9. node 上传文件 路径 重命名等问题

    最近在学习node,想做一个简单的网站.首先想到的是上传文件的功能,查了下,发现有一个formidable模块,操作方便,便拿来尝试了一下,结果很纠结. 下载安装的就不用说了,用npm即可.说一下,自 ...

  10. DNS解析

    大家好,今天51开源给大家介绍一个在配置文件,那就是/etc/resolv.conf.很多网友对此文件的用处不太了解.其实并不复杂,它是DNS客户机配置文件,用于设置DNS服务器的IP地址及DNS域名 ...