大意:问你每次涨幅为1的路径有几条,必须要走到尽头
思路:类似于这种每个状态都要取决于上一个状态的图,可以试试拓扑排序
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int mod = 1e9+7;
const int maxn = 1005;
int maps[maxn][maxn],in[maxn][maxn],out[maxn][maxn];//in记录入度,out记录出度
ll dp[maxn][maxn][5];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int n,m;
void Top_sort(){
queue<pair<int,int> >q;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!in[i][j]){
q.push(make_pair(i,j));
dp[i][j][1]=1;
}
}
}
while(!q.empty()){
int nowx=q.front().first;
int nowy=q.front().second;
q.pop();
for(int i=0;i<4;i++){
int x=nowx+dir[i][0];
int y=nowy+dir[i][1];
if(x>=1&&x<=n&&y>=1&&y<=m&&maps[x][y]==maps[nowx][nowy]+1){
dp[x][y][2]=(dp[x][y][2]+dp[nowx][nowy][1])%mod;
dp[x][y][3]=(dp[x][y][3]+dp[nowx][nowy][2])%mod;
dp[x][y][4]=(dp[x][y][4]+dp[nowx][nowy][3]+dp[nowx][nowy][4])%mod;
if(--in[x][y]==0){
q.push(make_pair(x,y));
}
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&maps[i][j]);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=0;k<4;k++){
int x=i+dir[k][0];
int y=j+dir[k][1];
if(x>=1&&x<=n&&y>=1&&y<=m){
if(maps[x][y]==maps[i][j]+1){
out[i][j]++;
}else if(maps[x][y]==maps[i][j]-1){
in[i][j]++;
}
}
}
}
}
Top_sort();
ll ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!out[i][j]){
ans=(ans+dp[i][j][4])%mod;
}
}
}
printf("%lld\n",ans);
return 0;
}
这题貌似还可以用记忆化搜索,到时候在补上code。。。。