poj 1084 舞蹈链(纠结题)
此题反正我自己是认为poj给的数据范围是有错的,不知道是不是自己太弱了,有大神在的话,欢迎来呸!
其实目的就在于建图,搞的我后来建了一个无比纠结的图,先建立了火柴棍和正方形的一个全图,然后再删除一些火柴和正方形
其实舞蹈链就是一个剪枝的深搜,好好理解就是的。数据n应该大于5的。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
int const N = ;
int n;
int des,dnum;
int mark[N][N],map[N][N];
int rvis[N],cvis[N]; int L[N],R[N],U[N],D[N];
int S[N];
int nCol[N];
int nRow[N];
bool answer[N+];
int best;
bool hash[N]; void init(int row,int col)
{
int r=row;
int w=col;
for (int i=;i<=w;i++)
{
L[i]=i-; R[i]=i+;
U[i]=D[i]=i;
}
L[]=w;
R[w]=;
int cnt=w+;
for (int i=;i<r;i++)
{
int head=cnt,tail=cnt;
for (int j=;j<w;j++)
{
int c = j+;
if(map[i][j]==)
{
S[c]++;
nCol[cnt]=c;
nRow[cnt]=i;
U[D[c]]=cnt;
D[cnt]=D[c];
U[cnt]=c;
D[c]=cnt;
L[cnt]=tail; R[tail]=cnt;
R[cnt]=head; L[head]=cnt;
tail=cnt;
cnt++;
}
}
}
}
void Remove(int x)
{
for (int i=D[x];i!=x;i=D[i])
{
L[R[i]]=L[i];
R[L[i]]=R[i];
S[nCol[i]]--;
}
}
void Resume(int x)
{
for (int i=D[x];i!=x;i=D[i])
{
L[R[i]]=R[L[i]]=i;
S[nCol[i]]++;
}
}
int Hash()
{
int ans=;
memset(hash,false,sizeof(hash));
for (int c=R[];c!=;c=R[c])
{
if (!hash[c])
{
hash[c]=;
ans++;
for (int i=D[c];i!=c;i=D[i])
for (int j=R[i];j!=i;j=R[j])
hash[nCol[j]]=;
}
}
return ans;
}
void dfs(int ans)
{
if (R[]==)
{
if(ans<best)
best=ans;
return;
}
int best2 = ans + Hash();
if (best2 >= best)
return; int c,minnum=;
for (int i=R[];i!=;i=R[i])
{
if (S[i]==) return;
if (S[i]<minnum)
{
minnum=S[i];
c=i;
}
}
for (int i=U[c];i!=c;i=U[i])
{
answer[nRow[i]]=true;
Remove(i);
for (int j=R[i];j!=i;j=R[j])
{Remove(j);}
dfs(ans+);
for (int j=L[i];j!=i;j=L[j])
{Resume(j);}
Resume(i);
answer[nRow[i]]=false;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(mark,,sizeof(mark));
int i,j,k,si,num=,ct=;
for(si=; si<=n; si++)
{
for(i=; i<=n-si+; i++)
{
for(j=; j<=n-si+; j++)
{
for(k=; k<si; k++)
{
mark[(i-)*(*n+)+j+k-][ct]=;
mark[(i-+si)*(*n+)+j+k-][ct]=;
mark[i*n+(i-)*(n+)+j+k*(*n+)-][ct]=;
mark[i*n+(i-)*(n+)+j+k*(*n+)+si-][ct]=;
}
ct++;
}
}
}
scanf("%d",&dnum);
memset(rvis,,sizeof(rvis));
memset(cvis,,sizeof(cvis));
memset(map,,sizeof(map));
for(i=;i<dnum;i++)
{
scanf("%d",&des);
rvis[des-]=;
for(j=;j<ct;j++)
{
if(mark[des-][j]==)
{
if(!cvis[j])
cvis[j]=;
}
}
}
int row=,col=,maxr=*n*n+*n;
for(i=;i<maxr;i++)
{
if(rvis[i])continue;
col=;
int f=;
for(j=;j<ct;j++)
{
if(cvis[j])continue;
if(mark[i][j])f=;
map[row][col++]=mark[i][j];
}
row++;
if(f)row--;
}
init(row,col);
best=;
dfs();
printf("%d\n",best);
}
return ;
}
poj 1084 舞蹈链(纠结题)的更多相关文章
- P4929 【模板】舞蹈链(DLX)
题目背景 本题是舞蹈链模板——精确覆盖问题 题目描述 给定一个N行M列的矩阵,矩阵中每个元素要么是1,要么是0 你需要在矩阵中挑选出若干行,使得对于矩阵的每一列j,在你挑选的这些行中,有且仅有一行的第 ...
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...
- DLX舞蹈链 hdu5046
题意: 在N个城市选出K个城市,建飞机场(1 ≤ N ≤ 60,1 ≤ K ≤ N),N个城市给出坐标,选择这K个机场,使得从城市到距离自己最近的机场的 最大的距离 最小. 输出这个最小值. 思路: ...
- [转] 舞蹈链(Dancing Links)——求解精确覆盖问题
转载自:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个 ...
- 舞蹈链 DLX
欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 舞蹈链是一个非常玄学的东西…… 问题模型 精确覆盖问题:在一个01矩阵中,是否可以选出一些行的集合,使得在这些行的集 ...
- 舞蹈链(DLX)
舞蹈链(DLX) Tags:搜索 作业部落 评论地址 一.概述 特别特别感谢这位童鞋His blog 舞蹈链是一种优美的搜索,就像下面这样跳舞- 舞蹈链用于解决精确覆盖或者重复覆盖的问题 你可以想象成 ...
- Dancing Links算法(舞蹈链)
原文链接:跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题 作者:万仓一黍 出处:http://grenet.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但 ...
- 转载 - 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
出处:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 ...
- [poj3074]Sudoku(舞蹈链)
题目链接:http://poj.org/problem?id=3074 舞蹈链精确覆盖的经典题目,一个数独每个位置的要求,可以得到以下四个约束1.每个位置有且只有一个数字2.每个位置的数字在一行只能出 ...
随机推荐
- “Assign Random Colors” is not working in 3ds Max 2015
Go to Customize -> Preferences…-> General (tab) Uncheck “Default to By Layer for New Nodes”
- sicily 1200欢迎提出优化方案
水题来的……我的做法是用a[10]数组表示每个数字出现的次数. 1200. Stick 限制条件 时间限制: 1 秒, 内存限制: 32 兆 题目描述 Anthony has collected a ...
- 堆排序 C++
1 堆排序拥有插入排序的优点 (是一种原地排序算法只需要存储常数个元素在输入数组以外 即省空间), 同时拥有合并排序算法的复杂度 nlgn,逼格有点高 2 堆数据结构 是一个数组对象,可以被视为一颗完 ...
- CentOS7 查看ip
查看内网:ip addr 查看公网:curl members.3322.org/dyndns/getip
- PHP - 5.4 Array dereferencing 数组值
在5.4之前我们直接获取数组的值得方法如下 <?php $str = 'a;b;c;d'; list($value) = explode(';',$str); echo $value; 结果为: ...
- 要做一款APP-解放双手
对方打字或发语音,我可以选择看屏幕或者听. 我说话,能够转化为文字.不需要点击开始按钮的那种.
- A-Frame 简介03
如果你想开始使用A-Frame可以通过以下几种方式: Play with CodePen Grab the Boilerplate Include the JS Build Install from ...
- x86与x64与x86_64
x86是指intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集,ntel官方文档里面称为“IA ...
- Java学习-Overload和Override的区别
1.Overload是重载的意思,Override是覆盖的意思,也就是重写. 2.重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同). 3 ...
- chkconfig用法
有时候为了方便管理,我们常常喜欢在Linux中将之安装为服务,然后就可以使用服务来管理. 但是当我们运行安装服务的命令时候,假设服务名为myservice #chkconfig --add myser ...