Digital Path (memorized search)

Preface

This question is a bronze question of 2019ICPC Nanjing, and it is an obvious memorized search question. But some optimization techniques for this problem are worth learning.

Title

Given a n ∗ mn∗mThe number matrix of n m , starting from any position, can only go up, down, left, and right one grid at a time, and the next position must be 1 larger than the current position. If you can continue to go back, you can’t stop. Find the total number A path with a length greater than or equal to 4.

data range

1 ≤ n , m ≤ 1000 1 \leq n,m \leq 1000 1n,m1000
− 1 0 9 ≤ a i , j ≤ 1 0 9 -10^9 \leq a_{i,j} \leq 10^9 109ai,j109

Ideas

In fact, this question is very similar to the previous question on skiing. Although this question adds a length limit, it can still be thought of by memorizing search. Memoized search can be transformed into doing dp in topological order on a DAG, and this problem is the same.
f (i, j, k) f(i,j,k)f(i,j,k ) means(i, j) (i, j)(i,j ) is the end point and the length iskkThe number of k paths. Because as long as the length is greater than or equal to 4, it meets the requirements, so the length greater than or equal to 4 can be classified into one category, that is,1 ≤ k ≤ 4 1 \leq k \leq 41k4 .
In addition, set two arrays in[i][j] and out[i][j] to record the in-degree and out-degree of each point. The point with an in-degree of 0 is the starting point of the path, and the point with an out-degree of 0 is The end of the path.
Do the topological order dp of the graph, the state transition equation can be roughly written as follows,f (tx, ty, k) = (f (tx, ty, k) + f (x, y, k − 1))% modf(tx, ty,k) = (f(tx,ty,k) + f(x,y,k-1))\%modf(tx,t y ,k)=(f(tx,t y ,k)+f(x,and ,k1))%mod

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 1010, mod = 1e9 + 7;

typedef pair<int,int> pii;

int n, m;
int g[N][N], in[N][N], out[N][N], f[N][N][5];
int dx[4] = {
    
    0,1,0,-1}, dy[4] = {
    
    1,0,-1,0};

void topsort()
{
    
    
    queue<pii> que;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(!in[i][j])
            {
    
    
                que.push({
    
    i,j});
                f[i][j][1] = 1;
            }
    
    while(que.size())
    {
    
    
        auto t = que.front();
        que.pop();
        int x = t.first, y = t.second;
        for(int i=0;i<4;i++)
        {
    
    
            int tx = x + dx[i], ty = y + dy[i];
            if(tx<1||tx>n||ty<1||ty>m) continue;
            if(g[tx][ty]==g[x][y]+1)
            {
    
    
                f[tx][ty][2] = (f[tx][ty][2] + f[x][y][1]) % mod;
				f[tx][ty][3] = (f[tx][ty][3] + f[x][y][2]) % mod;
				f[tx][ty][4] = (f[tx][ty][4] + f[x][y][3] + f[x][y][4]) % mod;
				if(--in[tx][ty]==0)	que.push({
    
    tx,ty});
            }
        }
    }
}

int main()
{
    
    
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&g[i][j]);
    
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            for(int k=0;k<4;k++)
            {
    
    
                int tx = i + dx[k], ty = j + dy[k];
                if(tx<1||tx>n||ty<1||ty>m) continue;
                if(g[tx][ty]==g[i][j]+1) out[i][j] ++;
                if(g[tx][ty]==g[i][j]-1) in[i][j] ++;
            }
    
    int res = 0;
    topsort();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(!out[i][j])
                res = (res + f[i][j][4]) % mod;
    
    printf("%d\n",res);
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43634220/article/details/108477466