Description

  The left figure below shows a complete 3*3 grid made with 2*(3*4) (=24) matchsticks. The lengths of all matchsticks are one. You can find many squares of different sizes in the grid. The size of a square is the length of its side. In the grid shown in the left figure, there are 9 squares of size one, 4 squares of size two, and 1 square of size three.

  Each matchstick of the complete grid is identified with a unique number which is assigned from left to right and from top to bottom as shown in the left figure. If you take some matchsticks out from the complete grid, then some squares in the grid will be destroyed, which results in an incomplete 3*3 grid. The right figure illustrates an incomplete 3*3 grid after removing three matchsticks numbered with 12, 17 and 23. This removal destroys 5 squares of size one, 3 squares of size two, and 1 square of size three. Consequently, the incomplete grid does not have squares of size three, but still has 4 squares of size one and 1 square of size two. 

  As input, you are given a (complete or incomplete) n*n grid made with no more than 2n(n+1) matchsticks for a natural number 5 <= n . Your task is to compute the minimum number of matchsticks taken 
  out to destroy all the squares existing in the input n*n grid.

 
  DLX可重复覆盖的问题,让我们去掉几根火柴,然后把所有的正方形都破坏掉。。。
  把每一个正方形都当做是一列,然后每一根火柴当做是一行。
 
  其中对于列和行的构造是麻烦的地方。。。。。。
  我是枚举每一个正方形,然后枚举这个正方形的每一条边。。。。。。
  
  其次就是Link之前要删除掉几行,这里TLE了N次,因为删除的时候要用到row,而且H[r]在某些情况下也应该改变才对(这里忘记了,导致一些数据循环停不下来。。。。。。)
 
代码如下:
#include<iostream>
#include<cstring> using namespace std; const int INF=10e8;
const int MaxN=;
const int MaxM=;
const int MaxNode=MaxN*MaxM; struct DLX
{
int L[MaxNode],R[MaxNode],U[MaxNode],D[MaxNode],col[MaxNode],row[MaxNode];
int S[MaxM],H[MaxN];
int n,m,size;
int ans; void init(int _n,int _m)
{
n=_n;
m=_m; for(int i=;i<=m;++i)
{
U[i]=D[i]=i;
R[i]=i+;
L[i]=i-;
row[i]=; // !!! S[i]=;
} R[m]=;
L[]=m; size=m;
ans=INF; for(int i=;i<=n;++i) // !!!
H[i]=-;
} void Link(int r,int c)
{
col[++size]=c;
++S[c];
row[size]=r; U[size]=U[c];
D[size]=c;
D[U[c]]=size;
U[c]=size; if(H[r]==-)
H[r]=L[size]=R[size]=size;
else
{
L[size]=L[H[r]];
R[size]=H[r];
R[L[H[r]]]=size;
L[H[r]]=size;
}
} void remove(int c)
{
for(int i=D[c];i!=c;i=D[i])
{
R[L[i]]=R[i];
L[R[i]]=L[i];
}
} void remove1(int r)
{
if(H[r]==-)
return; for(int i=U[H[r]];i!=H[r];i=U[i])
{
if(H[row[i]]==i) // !!!
{
if(R[i]==i)
H[row[i]]=-;
else
H[row[i]]=R[i];
} L[R[i]]=L[i];
R[L[i]]=R[i];
} for(int i=R[H[r]];i!=H[r];i=R[i])
for(int j=U[i];j!=i;j=U[j])
{
if(H[row[j]]==j)
{
if(R[j]==j)
H[row[j]]=-;
else
H[row[j]]=R[j];
} L[R[j]]=L[j];
R[L[j]]=R[j];
}
} void resume(int c)
{
for(int i=U[c];i!=c;i=U[i])
R[L[i]]=L[R[i]]=i;
} bool vis[MaxM]; int getH()
{
int ret=; for(int c=R[];c!=;c=R[c])
vis[c]=; for(int c=R[];c!=;c=R[c])
if(vis[c])
{
++ret;
vis[c]=; for(int i=D[c];i!=c;i=D[i])
for(int j=R[i];j!=i;j=R[j])
vis[col[j]]=;
} return ret;
} void Dance(int d)
{
if(d+getH()>=ans)
return; if(R[]==)
{
if(d<ans)
ans=d; return;
} int c=R[]; for(int i=R[];i!=;i=R[i])
if(S[i]<S[c])
c=i; for(int i=D[c];i!=c;i=D[i])
{
remove(i); for(int j=R[i];j!=i;j=R[j])
remove(j); Dance(d+); for(int j=L[i];j!=i;j=L[j])
resume(j); resume(i);
}
}
}; int N;
DLX dlx;
int ans1[]={,,,,,}; void slove()
{
dlx.init(*N*(N+),N*(N+)*(*N+)/); int t1,t2;
int cou=;
int K,a; cin>>K; if(K==)
{
cout<<ans1[N]<<endl;
return;
} for(int i=;i<=N;++i)
for(int j=;j<=(N-i+)*(N-i+);++j)
{
++cou; t1=(j-)%(N-i+)++(*N+)*((j-)/(N-i+)); for(int k=;k<i;++k)
{
dlx.Link(k+t1,cou);
dlx.Link((*N+)*k+t1+i-+N+,cou);
dlx.Link((*N+)*k+t1+N,cou);
dlx.Link(k+t1+i*(*N+),cou);
}
} for(int i=;i<K;++i)
{
cin>>a; dlx.remove1(a);
} dlx.Dance(); if(dlx.ans==INF)
cout<<<<endl;
else
cout<<dlx.ans<<endl;
} int main()
{
ios::sync_with_stdio(false); int T;
cin>>T; while(T--)
{
cin>>N; slove();
} return ;
}

(中等) POJ 1084 Square Destroyer , DLX+可重复覆盖。的更多相关文章

  1. UVA - 1603 Square Destroyer (DLX可重复覆盖+IDA*)

    题目链接 给你一个n*n的由火柴组成的正方形网格,从中预先拿掉一些火柴,问至少还需要拿掉多少火柴才能破坏掉所有的正方形. 看到这道题,我第一反应就是——把每根火柴和它能破坏掉的正方形连边,不就是个裸的 ...

  2. [DLX反复覆盖] poj 1084 Square Destroyer

    题意: n*n的矩形阵(n<=5),由2*n*(n+1)根火柴构成,那么当中会有非常多诸如边长为1,为2...为n的正方形,如今能够拿走一些火柴,那么就会有一些正方形被破坏掉. 求在已经拿走一些 ...

  3. (中等) HDU 5046 Airport ,DLX+可重复覆盖+二分。

    Description The country of jiuye composed by N cites. Each city can be viewed as a point in a two- d ...

  4. (简单) FZU 1686 神龙的难题 , DLX+可重复覆盖。

    Description 这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就 ...

  5. HDU 3957 Street Fighter(搜索、DLX、重复覆盖+精确覆盖)

    很久以前就看到的一个经典题,一直没做,今天拿来练手.街霸 给n<=25个角色,每个角色有 1 or 2 个版本(可以理解为普通版以及爆发版),每个角色版本可以KO掉若干人. 问最少选多少个角色( ...

  6. poj1084Square Destroyer(LDX解重复覆盖)

    题目请戳这里 题目大意:给一个n*n的用单位长度的木棍拼起来的网格图,给每个木棍按图示编号,编号范围1~2*n*(n+1).现在已知图中已经去掉了k个木棍,求还要至少去掉几根木棍能使网格图中不存在正方 ...

  7. 【POJ】1084 Square Destroyer

    1. 题目描述由$n \times n, n \in [1, 5]$的正方形由$2 \times n \times (n+1)$根木棍组成,可能已经有些木棍被破坏,求至少还需破坏多少木根,可以使得不存 ...

  8. hdu5064 DLX可重复覆盖+二分

    这题题意是 给了n个城市 在其中小于等于k个城市建立机场然后 使得最远的那个离机场的城市距离最短 二分答案 ,我们对于每次的mid 重新建图然后再来一次DLX,每个点可以覆盖的点建立一条联系就ok了 ...

  9. (中等) HDU 3335 , DLX+重复覆盖。

    Description As we know,the fzu AekdyCoin is famous of math,especially in the field of number theory. ...

随机推荐

  1. How To Add Swap on Ubuntu 14.04

    https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-14-04 How To Add Swap on ...

  2. Openlayer 3 图层列表控件(自定义)

    <body><div id="map"></div><div id="layerControl" class=&quo ...

  3. Funny Game

    Funny Game time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  4. linux 查看磁盘、文件夹、文件大小(df du)

    du 查看文件夹大小 1.查看当前文件夹中所有文件夹及其子文件夹的大小,注意是文件夹大小,不是文件 # du -h -rw-r--r-- 1 root root 82785865 6月 9 15:53 ...

  5. 求N以内与N互质的数的和

    题目连接 /* 求所有小于N且与N不互质的数的和. 若:gcd(n,m)=1,那么gcd(n,n-m)=1; sum(n)=phi(n)*n/2; //sum(n)为小于n的所有与n互质的数的和 // ...

  6. 设计模式-中介者模式(Mediator)

    /***中介者模式在消息队列中的应用*/package test.mediator; public abstract class Message { private Messages messages ...

  7. JS-DOM元素灵活查找

    用className选择元素 封装成函数 <title>无标题文档</title> <script> /* window.onload=function () { ...

  8. UVALive 2517 Moving Object Recognition(模拟)

    题目看上去很吓人,很高端,但其实很简单,不要被吓到,照搬题目的公式就可以了. 方法:用BFS求出最大块和重心,找出题目公式需要的未知量,然后套到题目公式里就可以求出答案了. 代码: #include& ...

  9. elasticsearch 索引优化

    ES索引优化篇主要从两个方面解决问题,一是索引数据过程:二是检索过程.  索引数据过程我在上面几篇文章中有提到怎么创建索引和导入数据,但是大家可能会遇到索引数据比较慢的过程.其实明白索引的原理就可以有 ...

  10. 转:Java eclipse下 Ant build.xml实例详解

    在有eclipse集成环境下ant其实不是很重要,但有些项目需要用到,另外通过eclipse来学习和理解ant是个很好的途径,所以写他demo总结下要点,希望能够帮到大家. 一.本人测试环境eclip ...