zoukankan      html  css  js  c++  java
  • FZU 1686 神龙的难题 (DLX)

    神龙的难题
    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
    Appoint description: 

    Description

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

    Input

    数据有多组,你要处理到EOF为止.每组数据第一行有两个数,n,m,(1<=n,m<=15)表示这次任务的地区范围. 然后接下来有n行,每行m个整数,如为1表示该点有怪物,为0表示该点无怪物.然后接下一行有两个整数,n1,m1 (n1<=n,m1<=m)分别表示米格拉一次能攻击的行,列数(行列不能互换),假设米格拉一单位时间能发出一个火球,所有怪物都可一击必杀.

    Output

    输出一行,一个整数,表示米格拉消灭所有魔物的最短时间.

    Sample Input

    4 4 1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1 2 2 4 4 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 2 2

    Sample Output

    4 1
     
     
     
    做DLX做得我都恶心了,每次都是TTTTTTT,这题T了两天,没话说了。
    把每个有怪物的点作为列,每次攻击能达到的区域作为行,问题就转化为最少选取多少行可以使得所有列都被覆盖。重复覆盖,A*剪枝。
      1 #include <iostream>
      2 #include <string>
      3 #include <cstring>
      4 #include <cstdio>
      5 using    namespace    std;
      6 
      7 const    int    HEAD = 0;
      8 const    int    SIZE = 20 * 20 * 20 * 20;
      9 const    int    INF = 0x7fffffff;
     10 bool    VIS[SIZE];
     11 int    U[SIZE],D[SIZE],L[SIZE],R[SIZE],C[SIZE],S[SIZE],LOC[SIZE];
     12 int    COUNT,ANS;
     13 int    N,M;
     14 
     15 int    h(void);
     16 void    ini(void);
     17 void    dancing(int);
     18 void    remove(int);
     19 void    resume(int);
     20 void    debug(void);
     21 int    main(void)
     22 {
     23     int    n,m;
     24 
     25     while(scanf("%d%d",&N,&M) != EOF)
     26     {
     27         ini();
     28         scanf("%d%d",&n,&m);
     29 
     30         for(int i = 1;i + n - 1 <= N;i ++)
     31             for(int j = 1;j + m - 1 <= M;j ++)
     32             {
     33                 int    first = COUNT;
     34                 for(int k = 0;k < n;k ++)
     35                     for(int l = 0;l < m;l ++)
     36                     {
     37                         int    loc = LOC[(i + k - 1) * M + j + l];
     38                         if(loc != -1)
     39                         {
     40                             L[COUNT] = COUNT - 1;
     41                             R[COUNT] = COUNT + 1;
     42                             U[COUNT] = U[loc];
     43                             D[COUNT] = loc;
     44 
     45                             D[U[loc]] = COUNT;
     46                             U[loc] = COUNT;
     47                             S[loc] ++;
     48                             C[COUNT] = loc;
     49                             COUNT ++;
     50                         }
     51                     }
     52                 if(first != COUNT)
     53                 {
     54                     L[first] = COUNT - 1;
     55                     R[COUNT - 1] = first;
     56                 }
     57             }
     58         dancing(0);
     59         printf("%d
    ",ANS);
     60     }
     61 
     62     return    0;
     63 }
     64 
     65 void    ini(void)
     66 {
     67     ANS = INF;
     68     COUNT = 1;
     69     int    box;
     70 
     71     for(int i = 1;i <= N;i ++)
     72         for(int j = 1;j <= M;j ++)
     73         {
     74             scanf("%d",&box);
     75             if(box)
     76             {
     77                 L[COUNT] = COUNT - 1;
     78                 R[COUNT] = COUNT + 1;
     79                 U[COUNT] = D[COUNT] = COUNT;
     80                 C[COUNT] = COUNT;
     81                 S[COUNT] = 0;
     82                 LOC[(i - 1) * M + j] = COUNT;
     83                 COUNT ++;
     84             }
     85             else
     86                 LOC[(i - 1) * M + j] = -1;
     87         }
     88     if(COUNT != 1)
     89     {
     90         R[COUNT - 1] = HEAD;
     91         L[HEAD] = COUNT - 1;
     92         R[HEAD] = 1;
     93     }
     94     else
     95         R[HEAD] = L[HEAD] = HEAD;
     96 }
     97 
     98 void    dancing(int k)
     99 {
    100     if(R[HEAD] == HEAD)
    101     {
    102         ANS = ANS < k ? ANS : k;
    103         return    ;
    104     }
    105     if(k + h() >= ANS)
    106         return    ;
    107 
    108     int    c = R[HEAD];
    109     for(int i = L[HEAD];i != HEAD;i = L[i])
    110         if(S[i] < S[c])
    111             c = i;
    112 
    113     for(int i = D[c];i != c;i = D[i])
    114     {
    115         remove(i);
    116         for(int j = R[i];j != i;j = R[j])
    117             remove(j);
    118         dancing(k + 1);
    119         for(int j = L[i];j != i;j = L[j])
    120             resume(j);
    121         resume(i);
    122     }
    123 
    124     return    ;
    125 }
    126 
    127 void    remove(int c)
    128 {
    129     for(int i = D[c];i != c;i = D[i])
    130     {
    131         L[R[i]] = L[i];
    132         R[L[i]] = R[i];
    133     }
    134 }
    135 
    136 void    resume(int c)
    137 {
    138     for(int i = U[c];i != c;i = U[i])
    139     {
    140         L[R[i]] = i;
    141         R[L[i]] = i;
    142     }
    143 }
    144 
    145 int    h(void)
    146 {
    147     for(int i = R[HEAD];i;i = R[i])
    148         VIS[i] = false;
    149 
    150     int    sum = 0;
    151     for(int i = R[HEAD];i != HEAD;i = R[i])
    152         if(!VIS[i])
    153         {
    154             sum ++;
    155             VIS[i] = true;
    156             for(int j = D[i];j != i;j = D[j])
    157                 for(int k = R[j];k != j;k = R[k])
    158                     VIS[C[k]] = true;
    159         }
    160 
    161     return    sum;
    162 }
  • 相关阅读:
    Mybatis使用map传递参数与模糊查询写法
    mybatis实现简单的crud
    普通maven项目导入mybatis依赖后找不到程序包(已解决)
    MarkDown语法学习
    CentOS 7 配置hadoop(一) 安装虚拟机(伪分布)
    CentOS 7 配置hadoop(二) 配置hdfs(伪分布)
    生成32个的字母加数字
    mysql 横变竖 竖变横
    Java实现短息验证
    spring+springmvc+mybatis+Redis的配置文件
  • 原文地址:https://www.cnblogs.com/xz816111/p/4442239.html
Copyright © 2011-2022 走看看