• NOIP1996 提高组 挖地雷


    From : http://www.tsinsen.com/ViewGProblem.page?gpid=A1105
     
    问题描述
      在一个地图上有N个地窖(N<=12),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。

    [题目要求]
      当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,每个地窖只能经过一次,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
    输入格式
      第一行一个数n。
      第二行n个数wi表示每个点的地雷数。
      随后n-1行若干个数。第i行第j个数表示i与i+j是否连通。1为连通,0为不连通。
    输出格式
      K1--K2--……….K(挖地雷的顺序)
      MAX=ans (挖地雷的数量)
      如果有多种方案则输出字典序最小的方案。
    样例输入
    5
    10 8 4 7 6
    1 1 1 1
    0 0 0
    1 1
    1
    样例输出
    2-1-3-4-5
    MAX=35
    数据规模和约定
      n<=12
     
    解决方案:
          基本思想: 深度优先搜索(DFS)或者称为回溯法(Backtracking)
          下面是C语言源代码
     1 #include <stdio.h>
     2 
     3 #define M   12
     4 
     5 typedef struct vector {
     6     int len;
     7     int data[M];
     8 } Vector;          // 向量, 用来存储挖雷的顺序
     9 
    10 
    11 int mine[M];      // mine[i] 表示第i个地窖中的地雷数,注意:这里i从0开始
    12 int mark[M];      // 标记,mark[i] 表示第i个地窖是否已被挖过
    13 int adjm[M][M];   // 邻接矩阵,表示地窖之间的连通关系
    14 int N;            // 地窖数
    15 int cmax, max;    // 分别为当前挖到的地雷数 和 能够挖到的最大地雷数
    16 Vector cvector, vector; // cmax 和 max 对应的挖雷顺序
    17 
    18 
    19 void sweep(int n) {
    20     int i, j;
    21     int flag = 1; 
    22     for (i = 0; i < N; i++) {
    23         if (adjm[n][i] == 1 && mark[i] == 0) {
    24             flag = 0;
    25             mark[i] = 1;
    26             cmax += mine[i];
    27             cvector.data[cvector.len++] = i;
    28             sweep(i);
    29             cvector.len--;
    30             cmax -= mine[i];
    31             mark[i] = 0;
    32         }
    33     }
    34     if (flag) { // 已挖到当前路径最大雷数
    35         if (cmax > max) {
    36             max = cmax;
    37             vector.len = cvector.len;
    38             for (j = 0; j < cvector.len; j++) {
    39                 vector.data[j] = cvector.data[j];
    40             }
    41         }
    42     }
    43 }
    44 
    45 
    46 int main() {
    47     int i, j;
    48     scanf("%d", &N);
    49     for (i = 0; i < N; i++) {
    50         scanf("%d", &mine[i]);
    51         adjm[i][i] = 0;
    52         mark[i] = 0;
    53     }
    54     for (i = 0; i < N; i++) {
    55         for (j = i + 1; j < N; j++) {
    56             scanf("%d", &adjm[i][j]);
    57             adjm[j][i] = adjm[i][j];
    58         }
    59     }
    60 
    61     max = 0, cmax = 0;
    62     for (i = 0; i < N; i++) {
    63         cvector.data[0] = i;
    64         cvector.len = 1;
    65         cmax = mine[i];
    66         mark[i] = 1;
    67         sweep(i);
    68         mark[i] = 0;
    69     }
    70 
    71     printf("%d", vector.data[0] + 1);
    72     for (i = 1; i < vector.len; i++) {
    73         printf("-%d", vector.data[i] + 1);
    74     }
    75     printf("
    MAX=%d
    ", max);
    76 
    77     return 0;
    78 }
  • 相关阅读:
    autocomplete
    ORM组件 ELinq (一)首航之旅
    ORM组件 ELinq 系列
    Jet 驱动对CRUD的支持
    ORM组件 ELinq 更新日志
    年度开源力作ORM组件 ELinq诞生了
    Excel 连接字符串详解
    国内开源ORM组件 ELinq正式版发布
    Firebird 问题总结
    ORM组件 ELinq (二) 映射配置之Table
  • 原文地址:https://www.cnblogs.com/william-cheung/p/3473890.html
Copyright © 2020-2023  润新知