C. Digital Path(矩阵统计合法路径)

题:https://nanti.jisuanke.com/t/42397

题意:给定矩阵,若相邻位置比当前位置多1,那么就可以从当前位置走到此相邻位置,定义一条合法路径为经过位置数大于等于4,一条路径是能扩增就扩增,不能截取一段来做路径,问给定矩阵有多少条合法路径。

分析:在相邻点判断建有向边,用拓扑序去跑DAG,dp记录各自长度。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
const int M=1e3+3;
const int N=2e6+6;
const int mod=1e9+7;
int a[M][M],in[N];
ll dp[N][5];
vector<int>g[N];
int nex[]={0,0,1,-1};
int ney[]={1,-1,0,0};
queue<int>que;
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&a[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+nex[k];
                int ty=j+ney[k];
                if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[i][j]==a[tx][ty]-1){
                    int u=(i-1)*m+j;
                    int v=(tx-1)*m+ty;
                    g[u].pb(v);
                    in[v]++;
                }
            }
        }
    }
    for(int i=1;i<=n*m;i++)
        if(in[i]==0)
            que.push(i),dp[i][1]=1;
    ll ans=0;
    while(!que.empty()){
        int now=que.front();
        que.pop();
        int f=0;
        for(auto v:g[now]){
            dp[v][2]=(dp[v][2]+dp[now][1])%mod;
            dp[v][3]=(dp[v][3]+dp[now][2])%mod;
            dp[v][4]=(dp[v][4]+dp[now][3]+dp[now][4])%mod;
            if(--in[v]==0) que.push(v);
            f=1;
        }

        if(!f)///到点了
            ans=(ans+dp[now][4])%mod;
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

 

posted @ 2020-09-06 21:53  starve_to_death  阅读(353)  评论(0编辑  收藏  举报