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. 关于项目刚才还能运行的,重启Myeclipse就不能运行(报错)的解决方法

    这个是以为内存不足引起的,就是打开MyEclipse的时候,因为内存不足,没有加载完整的项目,这个时候需要重启电脑,即可解决问题.

  2. 这几个linux 命令

    原文: linux性能分析 http://www.cnblogs.com/peida/tag/linux%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90/ du -sh /da ...

  3. 【Tomcat】Tomcat配置之请求字符串编码

    默认情况下,如果tomcat中部署的webservice或者web网站需要有中文的请求参数,而这时候我们直接在浏览器中输入中文那么接受到的将是乱码,无法达到我们的需求,这时候我们就需要对Tomcat的 ...

  4. Windsock套接字I/O模型学习 --- 第二章

    1. select模型 select模型主要借助于apiselect来实现,所以先介绍一下select函数 int select( int nfds, // 忽略,仅是为了与 Berkeley 套接字 ...

  5. Swift\本地文件管理

    转载自:http://www.coloroud.com/2015/06/01/Swift-File-Manager/ 开头 看来Swift这趟浑水是非干不可,既然如此,那索性就来的彻底吧,来一次全方位 ...

  6. android ScrollView嵌套EditText

    editext.setOnTouchListener(new OnTouchListener() {                        @Override            publi ...

  7. Chapter 1 First Sight——9

    One of the best things about Charlie is he doesn't hover. 一件最好的事是查理兹他不在附近. He left me alone to unpac ...

  8. hdu_4467_Graph(莫队算法思想)

    题目连接:hdu_4467_Graph 题意:给你n个点,m条边,每条边有一个权值,有两个操作,一个是修改单点的颜色,一个是询问边的两个端点都为指定颜色的权值和 题解:这题如果暴力的话,就是维护3个a ...

  9. STL笔记之set

    //---------------------------------------------------------// set综述//------------------------------- ...

  10. Android 下得到 未安装APK包含信息 等

    很多情况下,我们需要通过APK文件来得到它的一些信息. (此时此APK不一定被安装了) 0. 基础知识:可以通过android.content.Context的方法 getPackageManager ...