poj1084Square Destroyer(LDX解重复覆盖)
题目大意:给一个n*n的用单位长度的木棍拼起来的网格图,给每个木棍按图示编号,编号范围1~2*n*(n+1).现在已知图中已经去掉了k个木棍,求还要至少去掉几根木棍能使网格图中不存在正方形.即破坏图中所有的正方形.n不超过5.
题目分析:n太小了啦,直接爆搜!dancing links优化之.将之转化成一个重复覆盖的模型.
n*n的完全网格图中存在n*(n+1)*(2*n+1)/6个正方形.给每一个编号,然后小木棍的编号图中给了,就按那个来.然后小木棍为行,正方形为列,建图.
注意题目已经给定的k个木棍要去掉.首先那k个木棍覆盖的正方形是不用建图的,然后那k个表头也要删掉.
然后关于木棍编号破坏的正方形的关系.好像很复杂的样子,不过因为n太小了,然后我就打表了
..不过好难数,数了一晚上....
正方形编号从1~n*(n+1)*(2*n+1)/6,顺序按边长递增从左上角到右下角.
详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 6;
const int M = 4000;//3300
const int NM = 56;//最大正方形个数
int n,K,num,ans;
int h[M],s[M],u[M],d[M],l[M],r[M],col[M];
bool flag[NM],vis[NM];
int stk[NM];
int table[5][61][NM] = {
{
{0},{1,1},{1,1},{1,1},{1,1},
},
{ {0},{2,1,5},{2,2,5},{2,1,5},{2,1,2},{2,2,5},{2,1,3},
{2,2,4},{2,3,5},{2,3,4},{2,4,5},{2,3,5},{2,4,5},
},
{ {0},{3,1,10,14},{4,2,10,11,14},{3,3,11,14},{3,1,10,14},
{3,1,2,11},{3,2,3,10},{3,3,11,14},{3,1,4,12},{4,2,5,12,13},
{3,3,6,13},{4,4,10,12,14},{4,4,5,11,13},{4,5,6,10,12},
{4,6,11,13,14},{3,4,7,10},{4,5,8,10,11},{3,6,9,11},
{3,7,12,14},{3,7,8,13},{3,8,9,12},{3,9,13,14},
{3,7,12,14},{4,8,12,13,14},{3,9,13,14},
},
{ {0},{4,1,17,26,30},{6,2,17,18,26,27,30},{6,3,18,19,26,27,30},{4,4,19,27,30},
{4,1,17,26,30},{4,1,2,18,27},{4,2,3,17,19},{4,3,4,18,26},{4,4,19,27,30},
{4,1,5,20,28},{5,2,6,20,21,29},{5,3,7,21,22,28},{4,4,8,22,29},
{6,5,17,20,26,28,30},{6,5,6,18,21,27,29},{6,6,7,17,19,20,22},{6,7,8,18,21,26,28},{6,8,19,22,27,29,30},
{4,5,9,17,23},{6,6,10,17,18,23,24},{6,7,11,18,19,24,25},{4,8,12,19,25},
{6,9,20,23,26,28,30},{6,9,10,21,24,27,29},{6,10,11,20,22,23,25},{6,11,12,21,24,26,28},{6,12,22,25,27,29,30},
{4,9,13,20,26},{5,10,14,20,21,27},{5,11,15,21,22,26},{4,12,16,22,27},
{4,13,23,28,30},{4,13,14,24,29},{4,14,15,23,25},{4,15,16,24,28},{4,16,25,29,30},
{4,13,23,28,30},{6,14,23,24,28,29,30},{6,15,24,25,28,29,30},{4,16,25,29,30},
},
{ {0},
{5,1,26,42,51,55},{8,2,26,27,43,44,51,52,55},{9,3,27,28,42,43,44,51,52,55},{8,6,4,28,29,43,44,51,52,55},{5,5,29,44,52,55},
{5,1,26,42,51,55},{5,1,2,27,43,52},{5,2,3,26,28,44},{5,3,4,27,29,42},{5,4,5,28,43,51},{5,5,29,44,52,55},
{5,1,6,30,45,53},{8,2,7,30,31,45,46,53,54},{9,3,8,31,32,45,46,47,53,54},{8,4,9,32,33,46,47,53,54},{5,5,10,33,47,54},
{8,6,26,30,42,45,51,53,55},{8,6,7,27,31,43,46,52,54},{8,7,8,26,28,30,32,44,47},{8,8,9,27,29,31,33,42,45},{8,9,10,28,32,43,46,51,53},{8,10,29,33,44,47,52,54,55},
{5,6,11,26,34,48},{8,7,12,26,27,34,35,48,49},{9,8,13,27,28,35,36,48,49,50},{8,9,14,28,29,36,37,49,50},{5,10,15,29,37,50},
{9,11,30,34,42,45,48,51,53,55},{9,11,12,31,35,43,46,49,52,54},{9,12,13,30,32,34,36,44,47,50},{9,13,14,31,33,35,37,42,45,48},{9,14,15,32,36,43,46,49,51,53},{9,15,33,37,44,47,50,52,54,55},
{5,11,16,30,38,42},{8,12,17,30,31,38,39,42,43},{9,13,18,31,32,39,40,42,43,44},{8,14,19,32,33,40,41,43,44},{5,15,20,33,41,44},
{8,16,34,38,45,48,51,53,55},{8,16,17,35,39,46,49,52,54},{8,17,18,34,36,38,40,47,51},{8,18,19,35,37,39,41,45,48},{8,19,20,36,40,46,49,51,53},{8,20,37,41,47,50,52,54,55},
{5,16,21,34,45,51},{8,17,22,34,35,45,46,51,52},{9,18,23,35,36,45,46,47,51,52},{8,19,24,36,37,46,47,51,52},{5,20,25,37,47,52},
{5,21,38,48,53,55},{5,21,22,39,49,54},{5,22,23,38,40,50},{5,23,24,39,41,48},{5,24,25,40,49,53},{5,25,41,50,54,55},
{5,21,38,48,53,55},{8,22,38,39,48,49,53,54,55},{9,23,39,40,48,49,50,53,54,55},{8,24,40,41,49,50,53,54,55},{5,25,41,50,54,55},
}
}; void init()
{
int i,c;
memset(h,0,sizeof(h));
memset(s,0,sizeof(s));
c = n * (n + 1) * (2 * n + 1)/6;
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]];
l[r[num]] = r[l[num]] = num;
}
else
{
h[i] = num;
l[num] = r[num] = num;
}
s[j] ++;
u[num] = u[j];
d[num] = j;
d[u[j]] = num;
u[j] = num;
col[num] = j;
num ++;
}
void del(int c)
{
for(int i = d[c];i != c;i = d[i])
l[r[i]] = l[i],r[l[i]] = r[i];
}
void recover(int c)
{
for(int i = u[c];i != c;i = u[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];j != k;k = r[k])
vis[col[k]] = true;
}
}
return ret;
}
void dfs(int k)
{
if(k + A() >= ans)
return;
if(!r[0])
{
ans = min(ans,k);
return ;
}
int mn = M;
int c,i,j;
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 = r[i];j != i;j = r[j])
del(j);
dfs(k + 1);
for(j = l[i];j != i;j = l[j])
recover(j);
recover(i);
}
} void build()
{
scanf("%d",&n);
memset(flag,false,sizeof(flag)); scanf("%d",&K);
int i,j;
for(i = 1;i <= K;i ++)
{
scanf("%d",&stk[i]);
for(j = 1;j <= table[n - 1][stk[i]][0];j ++)
flag[table[n - 1][stk[i]][j]] = true;
}
init();
for(i = 1;i <= (n + 1) * n * 2;i ++)
{
for(j = 1;j <= table[n - 1][i][0];j ++)
if(flag[table[n - 1][i][j]] == false)
ins(i,table[n - 1][i][j]);
}
int nmgb = 0;
for(i = 1;i <= n * (n + 1) * (n * 2 + 1)/6;i ++)
if(flag[i])
l[r[i]] = l[i],r[l[i]] = r[i];
}
void fuck()
{
ans = M;
dfs(0);
printf("%d\n",ans);
}
int main()
{
int t;scanf("%d",&t);
while(t --)
{
build();
fuck();
}
return 0;
}
//244K 0MS
poj1084Square Destroyer(LDX解重复覆盖)的更多相关文章
- (中等) POJ 1084 Square Destroyer , DLX+可重复覆盖。
Description The left figure below shows a complete 3*3 grid made with 2*(3*4) (=24) matchsticks. The ...
- UVA - 1603 Square Destroyer (DLX可重复覆盖+IDA*)
题目链接 给你一个n*n的由火柴组成的正方形网格,从中预先拿掉一些火柴,问至少还需要拿掉多少火柴才能破坏掉所有的正方形. 看到这道题,我第一反应就是——把每根火柴和它能破坏掉的正方形连边,不就是个裸的 ...
- 【转】DLX 精确覆盖 重复覆盖
问题描述: 给定一个n*m的矩阵,有些位置为1,有些位置为0.如果G[i][j]==1则说明i行可以覆盖j列. Problem: 1)选定最少的行,使得每列有且仅有一个1. 2)选定最少的行,使得每列 ...
- hdu5046(重复覆盖+二分)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5046 题意:要在n个城市里建造不超过k个机场覆盖所有城市,问机场城市之间最大距离最小为多少. 分析:二 ...
- hdu2295(重复覆盖+二分)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2295 题意::一个国家有n个城市,有m个地方可以建造雷达,最多可以建K个雷达(K>=1 & ...
- DLX 舞蹈链 精确覆盖 与 重复覆盖
精确覆盖问题:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 还有重复覆盖问题 dancing links 是 一种数据结构,用来优化搜索,不算是一种算法.(双向 ...
- UVA - 11214 Guarding the Chessboard (可重复覆盖,DLX+IDA*)
题目链接 正解是IDA*+四个方向判重,但由于是个裸的可重复覆盖问题,可以用DLX水过~ 每个格子与放上皇后能干掉的标记连边,跑可重复覆盖DLX.注意要用IDA*来优化,否则会超时. #include ...
- HDU 2295 Radar (二分 + Dancing Links 重复覆盖模型 )
以下转自 这里 : 最小支配集问题:二分枚举最小距离,判断可行性.可行性即重复覆盖模型,DLX解之. A*的启发函数: 对当前矩阵来说,选择一个未被控制的列,很明显该列最少需要1个行来控制,所以ans ...
- DLX精确覆盖与重复覆盖模板题
hihoCoder #1317 : 搜索四·跳舞链 原题地址:http://hihocoder.com/problemset/problem/1317 时间限制:10000ms 单点时限:1000ms ...
随机推荐
- 项目代码摘抄,dot的用法之1
function searchTags() { var list = $('#tags-list-select option:selected').val(); console.log(list); ...
- KVO和通知中心
苹果其实在语言层面为我们做了很多事,比如Category实现装饰模式的意图,target-action实现命令模式意图等等,对于观察者模式,苹果也提供了KVO和通知中心,给开发者提供了极大的便利. 观 ...
- Struts2复习(四)防止表单反复提交
1.採取请求转发的方式完毕表单内容的加入会造成内容的反复插入. 2.採取重定向的方式实现数据的加入不会导致数据的反复插入. 3.防止表单反复提交的两种方式 1) 通过重定向 2) 通过Sessi ...
- 内容高度小于窗口高度时版权div固定在底部
<!doctype html><html><head><meta charset="utf-8"><title>文档内容 ...
- SQL XML process
declare @data xml set @data=' <bookstore> <book category="COOKING"> <title ...
- if和switch
在 JavaScript 中,我们可使用以下条件语句:if 语句 - 只有当指定条件为 true 时,使用该语句来执行代码if...else 语句 - ...
- MVC上传文件受限制
mvc自带设置4M一下的字体可以上传,4M以上的字体需要对web.config进行设置 <system.web> <httpRuntime targetFramework=" ...
- spring与hibernate整合配置基于Annotation注解方式管理实务
1.配置数据源 数据库连接基本信息存放到properties文件中,因此先加载properties文件 <!-- jdbc连接信息 --> <context:property-pla ...
- 转: mysql create view 创建视图
以下的文章主要是对MySQL视图的描述,其中包括MySQ视图L概述,以及创建MySQL视图-create view与修改MySQL视图--alter view等相关内容的具体描述,以下就是文章的具体内 ...
- 如何使用Palette提取Bitmap的颜色
5.X提出了color palette 的概念,能够让主题动态的去适应当前的页面色调,让整个app色调看起来比较和谐统一 那么如何使用Palette呢,必不可少,我们需要在Android studio ...