• 2019ICPC南京 Digital Path(拓扑排序+dp)


    对于本题,可以发现是一种bfs不断向外扩展的情况,也就是当某个点周围所有比他小1的点都更新过他了,那么他才可以更新别人,这里就有一种拓扑排序的思想

    又因为题目告诉我们要找最长的,因此我们最后的答案某点,不能向外扩展,因此可以维护出度和入度,以入度为更新标准,以出度为是否能作为答案

    之后拓扑时直接修改dp值即可,表示i,j这个位置,长度为k的答案,这里直接将4以上的压缩到4,这样比较方便,并且满足复杂度。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int inf=0x3f3f3f3f;
    const int N=2e5+10;
    const int mod=1e9+7;
    int f[2010][1010][5];
    int n,m;
    int a[2110][2010];
    int dx[]={-1,0,1,0};
    int dy[]={0,1,0,-1};
    int in[2110][2010],out[2110][2010];
    void topo(){
        queue<pll> q;
        int i,j;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                if(!in[i][j]){
                    q.push({i,j});
                    f[i][j][1]=1;
                }
            }
        }
        while(q.size()){
            auto t=q.front();
            q.pop();
            i=t.first;
            j=t.second;
            for(int k=0;k<4;k++){
                int x=t.first+dx[k];
                int y=t.second+dy[k];
                if(x&&x<=n&&y&&y<=m){
                    if(a[x][y]==a[i][j]+1){
                        f[x][y][2]=(f[x][y][2]+f[i][j][1])%mod;
                        f[x][y][3]=(f[x][y][3]+f[i][j][2])%mod;
                        f[x][y][4]=(f[x][y][4]+f[i][j][3]+f[i][j][4])%mod;
                        in[x][y]--;
                        if(!in[x][y])
                        q.push({x,y});
                    }
                }
            }
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>m;
        int i,j;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                cin>>a[i][j];
            }
        }
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                for(int k=0;k<4;k++){
                    int x=i+dx[k];
                    int y=j+dy[k];
                    if(x&&x<=n&&y&&y<=m){
                        if(a[i][j]==a[x][y]+1){
                            in[i][j]++;
                        }
                        if(a[i][j]==a[x][y]-1){
                            out[i][j]++;
                        }
                    }
                }
            }
        }
        topo();
        ll ans=0;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                if(!out[i][j]){
                    ans=(ans+f[i][j][4])%mod;
                }
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    <Listener>HttpSessionListener和HttpSessionAttributeListener区别
    @WebFilter怎么控制多个filter的执行顺序
    Springboot+Mybatis+MySQL实例练习时踩坑记录
    Git学习篇之git remote add origin错误
    Springboot高版本中@ConfigurationProperties注解取消location属性
    mevan中GroupId和ArtifactId到底怎么填?
    sqrt()函数对素数判断的优化
    oj错误之char型超出范围
    排序算法之桶排序
    Spring中常用注解
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13511663.html
Copyright © 2020-2023  润新知