zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Educational Codeforces Round 67 D. Subarray Sorting
    2019 Multi-University Training Contest 5
    Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code
    Educational Codeforces Round 69 D. Yet Another Subarray Problem
    2019牛客暑期多校训练第六场
    Educational Codeforces Round 68 E. Count The Rectangles
    2019牛客多校第五场题解
    2019 Multi-University Training Contest 3
    2019 Multi-University Training Contest 2
    [模板] 三维偏序
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13511663.html
Copyright © 2011-2022 走看看