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
  • 相关阅读:
    ThinkPHP5.0更改框架的验证方法:对象->validate(true)->save();
    ThinkPHP5.0版本和ThinkPHP3.2版本的区别
    ThinkPHP5.0版本的优势在于:
    11: django-haystack+jieba+whoosh实现全文检索
    10: supervisor进程管理工具
    09: redis集群之sentinel
    08: python支付宝支付
    07: redis分布式锁解决超卖问题
    06:keepalive高可用集群(新)
    05: 使用docker部署nginx负载均衡
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13511663.html
Copyright © 2011-2022 走看看