Digital Path
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 1≤n,m≤1000
− 1 0 9 ≤ a i , j ≤ 1 0 9 -10^9 \leq a_{i,j} \leq 10^9 −109≤ai,j≤109
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 41≤k≤4 .
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 ,k−1))%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;
}