Luogu P2566 [SCOI2009] Weidoudou

 

 

Los dos enteros N y M en la primera fila de Entrada son las longitudes laterales de la matriz. Un número entero D en la segunda línea es el número total de beans. La tercera línea contiene D enteros V1 a VD, que son las puntuaciones de cada bean. A continuación, hay una matriz de caracteres N × M en la fila N para describir el estado de la matriz del juego. 0 representa un espacio y # representa un obstáculo. Los números del 1 al 9 indican respectivamente el número correspondiente de frijoles.

La salida contiene solo un número entero, que es la puntuación más alta posible.

Entrada de muestra

3 8 3

30 -100 30

00000000

010203 # 0

00000000

Salida de muestra

38

Rango de datos:

El 50% de los datos satisface 1≤D≤3.
El 100% de los datos cumple con 1≤D≤9, 1≤N, M≤10, -10000≤Vi≤10000.

Análisis: Esta pregunta es realmente desagradable. Me quedé atrapado en varias clases.

   Sin mencionar el título ...

   "Hablemos acerca de cómo juzgar si el polígono puede rodear a Doudou. Dibujemos un rayo de Doudou a la derecha para juzgar cuántas intersecciones con el polígono. Si hay números impares, Doudou está adentro".

     Sin embargo, puede haber casos en los que el rayo y un borde coinciden , el punto está dentro del polígono y se puede juzgar de esta manera que el punto está afuera.

 

   Como nos dirigimos hacia la derecha, solo necesitamos juzgar cuándo el objeto se mueve hacia arriba y hacia abajo, para que no haya coincidencia, y Doudou solo cruzará el borde del polígono.

   ② ¿Cómo hacer esta pregunta? Mirando los datos, es obvio que la presión es dp. La definición f [x] [y] [s] representa el punto de partida desde (x, y), el estado es s (qué granos están encerrados) y la longitud del polígono más corto encerrado. Tenemos que preprocesar la puntuación v [s] que rodea a Doudou en cada estado

    ¿Cómo derivar el siguiente estado del estado actual? Necesitamos determinar si cada Doudou todavía está dentro del polígono cuando el siguiente va a la siguiente cuadrícula. Según ①, puedes saber si Doudou todavía está adentro.

    Si cambia, deje que se invierta el bit i-ésimo del estado, lo que indica que Doudou está dentro o no.

    ¿Cómo obtener f [x] [y] [s]? Podemos ejecutar bfs o spfa. Dado que se atraviesa todo el gráfico desde el punto de partida, se puede acceder a la ruta y debemos volver al punto de partida.

    Finalmente, encuentre el valor máximo de v [s] -f [x] [y] [s].

1  / * *********************************************** *************************
 2      > Nombre del archivo: s.cpp
 3      > Autor: LiuGeXian
 4      > Correo: [email protected] 
 5      > Creado Hora: 2020/4/14 18:47:59
 6  ************************************* ********************************** * / 
7 #include <bits / stdc ++. H>
 8  const  int maxn = 11 ;
9  usando el  espacio de nombres estándar;
10  struct Node {
 11      int x, y, z;
     Nodo 12 ( inta, int b, int c) {
 13          x = a;
14          y = b;
15          z = c;
16      }
 17  };
18  int dx [ 5 ] = { 0 , 0 , 1 , - 1 };
19  int dy [ 5 ] = { 1 , - 1 , 0 , 0 };
20  int Max, f [maxn] [maxn] [ 1 << maxn], ans = - 1, p [maxn];
21  int d, n, m, g [maxn] [maxn], px [maxn], py [maxn], v [ 1 << maxn], vis [maxn] [maxn] [ 1 << maxn];
22 en línea int Jud ( int ax, int ay, int bx, int by, int az) {
 23      for ( int i = 1 ; i <= d; i ++ ) {
 24          if (((ax == px [i] && bx <px [i]) || (ax <px [i] && bx == px [i])) && por> py [i]) {
 25              az ^ = ( 1 << (i- 1 ));
26         }
 27      }
 28      return az;
29  }
 30  int t;
31 vacío en línea F ( int x, int y) {
 32      cola <Nodo> q;
33      q.push ((Nodo) {x, y, 0 });
34      memset (f, 0x3f , sizeof (f));
35      memset (vis, 0 , sizeof (vis));
36      f [x] [y] [ 0 ] = 0 ;
37      while (q.size ()) {
38          int ax = q.front (). X;
39          int ay = q.front (). Y;
40          int az = q.front (). Z;
41          vis [hacha] [ay] [az] = 0 ;
42          q.pop ();
43          para ( int k = 0 ; k < 4 ; k ++ ) {
 44              int bx = ax + dx [k];
45              int por = ay + dy [k];
46              int bz = az;
47              if (bx < 1 || por < 1|| bx> n || por> m) continuar ;
48              if (g [bx] [by]) continúa ;
49              if (k> = 2 ) bz = Jud (ax, ay, bx, by, az);
50              if (f [ax] [ay] [az] + 1 < f [bx] [by] [bz]) {
 51                  f [bx] [by] [bz] = f [ax] [ay] [az] + 1 ;
52                  if (! Vis [bx] [por] [bz])
 53                      vis [bx] [por] [bz] = 1 ;
54                      q.push ((Nodo) {bx, by, bz});
55              }
 56          }
 57     }
 58      para ( int s = 0 ; s <Max; s ++ ) {
 59          ans = max (ans, v [s] - f [x] [y] [s]);
60      }
 61  }
 62  int main () {
 63      scanf ( " % d% d " , & n, & m);
64      scanf ( " % d " , & d);
65      Máx = 1 << d;
66      para ( int i = 1 ; i <= d; i ++) scanf ( " % d ", & p [i]);
67      para ( int i = 0 ; i <Max; i ++ ) {
 68          para ( int j = 1 ; j <= d; j ++ ) {
 69              if (i & ( 1 << (j- 1 ))) v [i ] + = p [j];
70          }
 71      }
 72      para ( int i = 1 ; i <= n; i ++ ) {
 73          para ( int j = 1 ; j <= m; j ++ ) {
 74              char ch;
75             scanf ( " % c " , & ch);
76              if (ch == ' # ' ) g [i] [j] = - 1 ;
77              más  si (ch == ' 0 ' ) g [i] [j] = 0 ;
78              else {
 79                  int num = ch - ' 0 ' ;
80                  g [i] [j] = num;
81                  px [num] = i;
82                  py [num] = j;
83              }
 84         }
 85      }
 86      para ( int i = 1 ; i <= n; i ++ ) {
 87          para ( int j = 1 ; j <= m; j ++ ) {
 88              if (! G [i] [j]) F (i j); 
89          }
 90      }
 91      cout << ans;
92      devuelve  0 ;
93 }
Ver código

 

Supongo que te gusta

Origin www.cnblogs.com/ghosh/p/12710191.html
Recomendado
Clasificación