FZU 1686 龙之谜 重复覆盖

兑换0,1模型,如。注意,数据的范围

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
using namespace std;
const int MaxM = 500;
const int MaxN = 500;
const int maxnode = MaxM*MaxN;
int K,n,m;
struct DLX
{
	int n,m,size;
	int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
	int H[MaxN],S[MaxM];
	int ands,ans[MaxN];
	void init(int _n,int _m)
	{
	    ands=0x3f3f3f3f;
		n = _n;
		m = _m;
		for(int i = 0;i <= m;i++)
		{
			S[i] = 0;
			U[i] = D[i] = i;
			L[i] = i-1;
			R[i] = i+1;
		}
		R[m] = 0; L[0] = m;
		size = m;
		for(int i = 1;i <= n;i++)
			H[i] = -1;
	}
	void Link(int r,int c)
	{
		++S[Col[++size]=c];
		Row[size] = r;
		D[size] = D[c];
		U[D[c]] = size;
		U[size] = c;
		D[c] = size;
		if(H[r] < 0)H[r] = L[size] = R[size] = size;
		else
		{
			R[size] = R[H[r]];
			L[R[H[r]]] = size;
			L[size] = H[r];
			R[H[r]] = size;
		}
	}
	void remove(int c)
	{
		for(int i = D[c];i != c;i = D[i])
			L[R[i]] = L[i], R[L[i]] = R[i];
	}
	void resume(int c)
	{
		for(int i = U[c];i != c;i = U[i])
			L[R[i]]=R[L[i]]=i;
	}
	bool v[maxnode];
	int f()
	{
		int ret = 0;
		for(int c = R[0];c != 0;c = R[c])v[c] = true;
		for(int c = R[0];c != 0;c = R[c])
			if(v[c])
			{
				ret++;
				v[c] = false;
				for(int i = D[c];i != c;i = D[i])
					for(int j = R[i];j != i;j = R[j])
						v[Col[j]] = false;
			}
		return ret;
	}
	void Dance(int d)
	{
	    if(d+f()>=ands) return;
		if(R[0] == 0) {ands=min(ands,d);return;}
		int c = R[0];
		for(int i = R[0];i != 0;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+1);
			for(int j = L[i];j != i;j = L[j])resume(j);
			resume(i);
		}
	}
}g;
int mp[20][20],sa,sb,id[20][20];
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        int tot=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&mp[i][j]);
                if(mp[i][j]) id[i][j]=++tot;
            }
        }
        scanf("%d%d",&sa,&sb);
        g.init(n*m,tot);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                for(int ii=i,cnt=1;cnt<=sa&&ii<n;ii++,cnt++)
                {
                    for(int jj=j,cnt2=1;cnt2<=sb&&jj<m;jj++,cnt2++)
                    {
                        if(mp[ii][jj])
                        {
                            g.Link(i*m+j+1,id[ii][jj]);
                        }
                    }
                }
            }
        }
        g.Dance(0);
        printf("%d\n",g.ands);
    }
    return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-10-24 11:16:16

FZU 1686 龙之谜 重复覆盖的相关文章

FZU 1686 DLX建图重复覆盖

Problem 1686 神龙的难题 Accept: 394    Submit: 1255 Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem Description 这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们不被魔物侵害.魔法使艾米莉就是这样的一个人.她骑着她的坐骑,神龙米格

FZU 1686 神龙的难题(重复覆盖问题&amp;舞蹈链)

题目链接:[kuangbin带你飞]专题三 Dancing Links D - 神龙的难题 题意 Description 这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们不被魔物侵害.魔法使艾米莉就是这样的一个人.她骑着她的坐骑,神龙米格拉一起消灭干扰人类生存的魔物,维护王国的安定.艾米莉希望能够在损伤最小的前提下完成任务.每次战斗前,她都用时间

FZU 1686 神龙的难题 重复覆盖

转换成0,1模型就好了,注意数据范围 #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h

FZU 1686 舞蹈链之可重复覆盖

点击打开链接 题意:中文题了 思路:做了几个舞蹈链的题目了,第一感觉总会想到去用网络流去写,哎YY一会就是错的,乖乖用舞蹈链来写把,对于这道题目我们可以将所有的1看成是列,然后行则是一个一个的小矩阵,每一行也就是小矩阵连接自己可以消灭的1,但是首先要给所有的1编一下号,再然后就是模版舞蹈链了 #include <vector> #include <stdio.h> #include <string.h> #include <stdlib.h> #includ

FZU 2165 v11(最小重复覆盖)

告诉你若干个(<=100)武器的花费以及武器能消灭的怪物编号,问消灭所有怪物(<=100)的最小花费...当然每个武器可以无限次使用,不然这题就太水了╮(╯▽╰)╭ 这题当时比赛的时候连题都还没看就结束了....赛后一看,果断是重复覆盖... 不过之后一直没敲...然后今天算是补回来吧,同时也把好久以前学的DLX复习一下... DLX的话,双向十字链表...具体的话,百度Google什么的dancing links... 一开始敲的时候还是挺顺利的,因为之前做过几次重复覆盖都是直接拿精确覆盖的

FZU 1686 神龙的难题(DLX重复覆盖)

FZU 1686 神龙的难题 题目链接 题意:中文题 思路:每一个1看成列,每个位置作为左上角的矩阵看成行,dlx重复覆盖即可 代码: #include <cstdio> #include <cstring> using namespace std; const int MAXNODE = 66666; const int INF = 0x3f3f3f3f; const int MAXM = 230; const int MAXN = 230; int K; struct DLX

FZU 1686 神龙的难题 DLX重复覆盖

DLX重复覆盖: 需要一个A*函数剪支 Problem 1686 神龙的难题 Accept: 462    Submit: 1401 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description 这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们不被魔物侵害.魔法使艾米莉

[DLX重复覆盖] fzu 1686 神龙的难题

题意: 中文题 思路: 想到是一个重复覆盖的问题,然后就是最少放多少个能覆盖满. 建图的话就是先标记一下哪些点有怪物,最多就是n*m个怪物. 然后就是行. 行的话就看输入的x和y能框住多少的范围了. 然后四重循环遍历一遍建边就ok了. 代码: #include"stdio.h" #include"algorithm" #include"string.h" #include"iostream" #include"cma

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

Description 这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们不被魔物侵害.魔法使艾米莉就是这样的一个人.她骑着她的坐骑,神龙米格拉一起消灭干扰人类生存的魔物,维护王国的安定.艾米莉希望能够在损伤最小的前提下完成任务.每次战斗前,她都用时间停止魔法停住时间,然后米格拉他就可以发出火球烧死敌人.米格拉想知道,他如何以最快的速度消灭敌人,减