题目请戳这里

题目大意:给一个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;}elseh[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;
}

转载于:https://www.cnblogs.com/riasky/p/3481865.html

poj2032Square Carpets(IDA* + dancing links)相关推荐

  1. dancing links x(舞蹈链算法)详解

    dancing links x 详解 大佬万仓一黍的blog 夜深人静写算法(九)- Dancing Links X(跳舞链) 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合, ...

  2. 算法帖——用舞蹈链算法(Dancing Links)求解俄罗斯方块覆盖问题

    问题的提出:如下图,用13块俄罗斯方块覆盖8*8的正方形.如何用计算机求解? 解决这类问题的方法不一而足,然而核心思想都是穷举法,不同的方法仅仅是对穷举法进行了优化 用13块不同形状的俄罗斯方块(每个 ...

  3. Dancing Links

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

  4. DLX (Dancing Links/舞蹈链)算法——求解精确覆盖问题

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

  5. zoj 3209 Dancing links/hust 1017

    Dancing links的题目. 具体的dancing links的介绍 看:http://blog.csdn.net/sunny606/article/details/7833551 思想还是好理 ...

  6. [学习笔记]舞蹈链(Dancing Links)C++实现(指针版)

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

  7. HDU 4069 Squiggly Sudoku【Dancing Links精确覆盖】

    跟普通的数独有一点点不同,先预处理一下再用Dancing Links进行精确覆盖即可. #include <iostream> #include <cstdio> #inclu ...

  8. Dancing Links中文版

    Dancing Links中文版(DLXcn) Donald E.Knuth, Stanford University 翻译 武汉武钢三中 吴豪 更正 排版 上海交通大学 隋清宇(sqybi) 最近更 ...

  9. 简单易懂的Dancing links讲解(4)

    DancingLinks的应用 把dancingLink应用于实际问题时,只有一个难点,就是如何把具体的问题转换为可以精确覆盖的01矩阵模型,一旦完成了这个步后,直接套用模板就可以解决问题了. 应用之 ...

最新文章

  1. 第四代自动泊车从APA到AVP技术
  2. TextView-- 测量文字宽度
  3. 718. Maximum Length of Repeated Subarray 最长重复子数组
  4. 计算机网络就业范围分析,计算机网络技术专业就业前景怎么样「就业形势分析」...
  5. Opencv实战【1】人脸检测并对ROI区域进行部分处理(变身乔碧萝!!!)
  6. ocp跟oce的区别 oracle_Oracle视频10g 11g认证视频教程 OCA/OCP 从入门到精通 数据库DBA...
  7. 程序员面试金典 - 面试题 08.05. 递归乘法(位运算)
  8. 企业实战_02_MyCat基本元素
  9. 如何在GitHub上下载开源文件
  10. java项目没有bin_WebAPI项目似乎没有将转换后的web.config发布到bin文件夹?
  11. replace使用案例--替换空格
  12. 十二、实战启动页(一)
  13. Python中字典的增、删、查
  14. 面向对象的三个特点:封装、继承、多态
  15. BootStrap 模态框禁用空白处点击关闭,手动显示隐藏,垂直居中
  16. 时间序列入门概念整理
  17. EJB - 环境设置
  18. 企业微信怎么填写服务器,勤哲Excel服务器软件做企业微信管理系统
  19. go编译成linux可执行,Golang 编译Mac、Linux、Windows多平台可执行程序
  20. Ping命令进行网络检测

热门文章

  1. 常见的集成逻辑门(CMOS\TTL\ECL)
  2. 机器学习中的算法-支持向量机(SVM)基础
  3. php分页操作,PHP实现适用于文件内容操作的分页类
  4. 程序员python工作_程序员如何在工作中进步
  5. mvc html 生成图片,asp.net mvc5 cs代码中获取视图生成后的HTML
  6. DT-06 For MQTT
  7. pytest单侧模块_入门汇总
  8. highcharts第一篇---简介和使用
  9. ajax长链接--拉实现
  10. python tkinter布局混用_[宜配屋]听图阁