Calculator-42397 2019ICPC Nanjing C-Digital Path (búsqueda memorizada)

Zhe, el matón, es condenado por todo tipo de maldades, como intimidar a los más débiles. Sus compañeros de equipo han sido maltratados durante mucho tiempo. Finalmente, decidieron no aguantar más a su amigo y huir a Digital Village, con el matón persiguiéndolo. Debido al terreno difícil y una cantidad considerable de caminos digitales escalonados, no se pueden detener fácilmente.

Familiarizarse con el terreno lo antes posible es importante para que estos inocentes escapen de la amenaza del acoso. Todo lo que necesitan ahora es contar el número de rutas digitales en Digital Village.

Para simplificar el problema, Digital Village se abstrae en una cuadrícula con nn filas y mm columnas llenas de números enteros. Un camino digital es un paseo continuo en la cuadrícula que satisface las siguientes condiciones:

  • las cajas adyacentes en el paseo comparten un borde común;
  • la caminata es máxima, que no se puede extender;
  • el paseo contiene al menos cuatro cajas;
  • yendo de un extremo al otro, el incremento de valores para dos casillas adyacentes es exactamente uno.

Aquí tenemos algunos ejemplos.

La ruta de la Figura 1 no es válida porque su longitud es inferior a 44.

La ruta de la Figura 2 no es válida porque no es continua.

La ruta de la Figura 3 no es válida porque se puede ampliar más.

La ruta de la Figura 4 tampoco es válida porque los valores de la ruta no se incrementan estrictamente en uno.

Las rutas digitales pueden superponerse parcialmente. En la Figura 5, hay 44 rutas digitales marcadas con diferentes colores.

Aporte

La primera línea contiene dos números enteros positivos nn y m (1≤n, m≤1000) m (1≤n, m≤1000) que describen el tamaño de la cuadrícula.

Cada una de las siguientes nn líneas contiene mm enteros, el jj-ésimo de los cuales, denotado por ai, j (−107≤ai, j≤107) ai, j (−107≤ai, j≤107), representa el valor de el cuadro en la segunda fila y la jj-ésima columna.

Producción

Genere el número de rutas digitales módulo (109 + 7) (109 + 7).

Entrada de muestra

3 5 
1 2 3 8 
7-1-1 4 5 6 
1 2 3 8 7

Salida de muestra

4

Entrada de muestra 2

4 4 
1 2 3 4 
2 3 4 3 
3 4 3 2 
4 3 2 1

Salida de muestra 2

dieciséis

Título:

Pregunte cuántos caminos en la matriz satisfacen estas condiciones:

(1) La longitud es de al menos 4

(2) El camino no se puede ampliar

(3) El peso de los puntos en la ruta aumenta en 1 en cada paso.

(4) Los dos puntos deben estar adyacentes entre sí o arriba y abajo.

Ideas:

La búsqueda de memoria dp [x] [y] [len] (1 \ leq len \ leq 4) significa el (x, y) número de caminos con longitud len al punto  . Los caminos con longitud> = 4 se marcan como longitud 4.

Ecuación de transferencia:, dp [x] [y] [len] + = dp [fx] [fy] [len - 1]donde el punto  (x, y) es (fx, fy) adyacente al punto  mp [x] [y] = mp [fx] [fy] + 1

Si len == 4, dp [x] [y] [len] también se puede realizar  dp [fx] [fy] [len] sobre la transferencia, es decir, dp [x] [y] [4] + = dp [fx] [fy] [4]

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int N = 1005;

ll mp[N][N], dp[N][N][5];
int n, m, dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};

//判是不是路径终点
bool check1(int x, int y) {
    for(int i = 0; i < 4; ++i) {
        int fx = x + dir[i][0];
        int fy = y + dir[i][1];
        if(fx >= 1 && fx <= n && fy >= 1 && fy <= m && mp[fx][fy] == mp[x][y] + 1) return 0;
    }
    return 1;
}

//判是不是路径起点
bool check2(int x, int y) {
    for(int i = 0; i < 4; ++i) {
        int fx = x + dir[i][0];
        int fy = y + dir[i][1];
        if(fx >= 1 && fx <= n && fy >= 1 && fy <= m && mp[fx][fy] == mp[x][y] - 1) return 0;
    }
    return 1;
}

ll dfs(int x, int y, int len) {
    if(len == 1) {
        if(check2(x, y)) dp[x][y][len] = 1;
        else dp[x][y][len] = 0;
        return dp[x][y][len];
    }
    if(dp[x][y][len] != -1) return dp[x][y][len] % mod;
    ll res = 0;
    for(int i = 0; i < 4; ++i) {
        int fx = x + dir[i][0];
        int fy = y + dir[i][1];
        if(fx < 1 || fx > n || fy < 1 || fy > m || mp[fx][fy] != mp[x][y] - 1) continue;
        res = (res + dfs(fx, fy, len - 1)) % mod;
        if(len == 4) res = (res + dfs(fx, fy, len)) % mod;
    }
    dp[x][y][len] = res % mod;
    return dp[x][y][len];
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            scanf("%lld", &mp[i][j]);
    ll ans = 0;
    memset(dp, -1, sizeof(dp));
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= m; ++j) {
            if(mp[i][j] != -1 && check1(i, j)) {
                ans = (ans + dfs(i, j, 4)) % mod;
            }
        }
    }
    printf("%lld\n", ans);
    return 0;
}
/*
2 4
1 2 3 4
3 3 4 1
*/

 

Supongo que te gusta

Origin blog.csdn.net/weixin_43871207/article/details/110938876
Recomendado
Clasificación