zoukankan      html  css  js  c++  java
  • [Luogu] 飞扬的小鸟

    https://www.luogu.org/problemnew/show/P1941

    Bfs or Dp

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 1e4 + 10;
    
    #define gc getchar()
    #define oo 99999999
    
    struct Node_1 {
        int X, D, U;
    } P[N];
    struct Node_2 {
        int U, D;
    } M[N];
    struct node {
        int x, y, step;
    };
    
    int n, m, k;
    int Answer = oo, Maxx;
    
    queue <node> Q;
    
    inline int read() {
        int x = 0;
        char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    }
    
    int up, down;
    int vis[N][1000];
    
    inline void Bfs() {
        for(int i = m; i >= 1; i --) {
            node now;
            now.x = 2;
            down = i - M[1].D, up = i + M[1].U;
            if(down > P[2].D && down < P[2].U && vis[2][down] == 0) {
                now.y = down;
                now.step = 0;
                vis[now.x][now.y] = 1;
                Q.push(now);
            }
    
            if(up > P[2].D && up < P[2].U && vis[2][up] == 0) {
                now.y = min(up, m);
                vis[now.x][now.y] = 1;
                now.step = 1;
                Q.push(now);
            }
    
        }
        while(!Q.empty()) {
            node topp = Q.front();
            Q.pop();
            Maxx = max(Maxx, topp.x);
            if(topp.x == n + 1) {
                Answer = min(Answer, topp.step);
                continue ;
            }
            int y = topp.y, x = topp.x;
            node nxt;
            nxt.x = x + 1;
            down = y - M[x].D, up = y + M[x].U;
            if(down > P[x + 1].D && down < P[x + 1].U) {
                nxt.y = down;
                nxt.step = topp.step;
                if(vis[nxt.x][nxt.y] == 0) {
                    vis[nxt.x][nxt.y] = nxt.step;
                    Q.push(nxt);
                } else {
                    if(vis[nxt.x][nxt.y] > nxt.step) {
                        Q.push(nxt);
                        vis[nxt.x][nxt.y] = nxt.step;
                    }
                }
            }
            nxt.y = up;
            nxt.step = topp.step;
            up = min(up, m);
            while(up > P[x + 1].D && up < P[x + 1].U) {
                nxt.y = min(nxt.y, m);
                if(vis[nxt.x][nxt.y] == 0) {
                    nxt.step ++;
                    vis[nxt.x][nxt.y] = nxt.step;
                    Q.push(nxt);
                } else {
                    if(vis[nxt.x][nxt.y] > nxt.step + 1) {
                        nxt.step ++;
                        Q.push(nxt);
                        vis[nxt.x][nxt.y] = nxt.step;
                    }
                }
                if(nxt.y == m) break;
                nxt.y += M[x].U;
                up = min(nxt.y, m);
            }
        }
    }
    
    int main() {
        n = read();
        m = read();
        k = read();
        for(int i = 1; i <= n; i ++)
            M[i].U = read(), M[i].D = read(), P[i].U = m + 1;
        P[n + 1].U = m + 1;
        for(int i = 1; i <= k; i ++) {
            int X = read() + 1;
            P[i].X = X;
            P[X].D = read();
            P[X].U = read();
        }
        Bfs();
        if(Answer != oo) cout << 1 << "
    " << Answer;
        else {
            cout << 0 << "
    ";
            int js(0);
            for(int i = 1; i <= k; i ++) if(P[i].X <= Maxx) js ++;
            cout << js;
        }
    
        return 0;
    }
    /*
    5 5 0
    3 3
    2 1
    2 3
    2 1
    3 2
    */
    View Code
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #define N 10003
    #define M 1003
    #define For(i,j,k) for(int i=j;i<=k;++i)
    int read() {
        int x=0,l=1;
        char ch=getchar();
        while(!isdigit(ch)) {
            if (ch=='-') l=-1;
            ch=getchar();
        }
        while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
        return x*l;
    }
    using namespace std;
    int a[N][M],x[N],y[N],hi[N]; //a存到当前点的最优步数
    short hk[M<<1],wal[M<<1]; //hk记列,wal记行,这只是循环队列,不要在意变量名
    bool fl[N][M],mp[N][M],li[N]; //fl--某个点有没有被走过,mp--某个点有没有管子,li--记录某一列能不能到
    int main() {
        int an,n=read(),m=read(),k=read(),mo,ha,jzm,l=0,r,ac,p=0,kk,ff;
        ac=m<<1;
        For(i,0,n-1) x[i]=read(),y[i]=read(),hi[i]=10000; //hi记录某一列上限,如果是最大值表示无上限
        For(i,1,k) {
            jzm=read(),mo=read(),ha=read(); //不要在意变量名x2
            For(j,1,mo) mp[jzm][j]=1;
            For(j,ha,m) mp[jzm][j]=1;
            hi[jzm]=ha-1; //mp,hi标记
        }
        r=m;
        For(i,1,m) wal[i]=i; //第0列入队
        while(l<r) {
            l++;
            mo=hk[l%ac];
            ha=wal[l%ac];
            ff=an=0;
            li[mo]=1;
            if (mo==n) continue;
            kk=min(m,hi[mo+1]);
            for(int i=ha+x[mo]; i<=kk; i+=x[mo]) { //枚举当前点可以到的点
                an++;
                if (mp[mo+1][i]) continue; //判断当前有没有管道(下面的,碰上面管道就退循环了)
                if (!fl[mo+1][i]) { //没走过就入队
                    fl[mo+1][i]=1;
                    r++;
                    hk[r%ac]=mo+1;
                    wal[r%ac]=i;
                    a[mo+1][i]=a[mo][ha]+an;
                } else if (a[mo+1][i]>a[mo][ha]+an) a[mo+1][i]=a[mo][ha]+an; //更新值
                if (fl[mo][i]&&a[mo][i]<=a[mo][ha]+an) {
                    ff=1;
                    break;
                }
                //重要剪枝!如果当前点顶上有点比他更优那就可以退了
                //但是在这之前的循环是必要的,因为这时走的点是他顶上那个点走不到的
            }
            if (!mp[mo+1][m]&&!ff) { //特判到顶的情况
                if (!fl[mo+1][m]) {
                    fl[mo+1][m]=1;
                    r++;
                    hk[r%ac]=mo+1;
                    wal[r%ac]=m;
                    a[mo+1][m]=a[mo][ha]+an+1;
                } else if (a[mo+1][m]>a[mo][ha]+an+1) a[mo+1][m]=a[mo][ha]+an+1;
            }
            if (ha-y[mo]>0) { //特判下降情况
                jzm=ha-y[mo];
                if (!mp[mo+1][jzm]) {
                    if (!fl[mo+1][jzm]) {
                        fl[mo+1][jzm]=1;
                        r++;
                        hk[r%ac]=mo+1;
                        wal[r%ac]=jzm;
                        a[mo+1][jzm]=a[mo][ha];
                    } else if (a[mo+1][jzm]>a[mo][ha]) a[mo+1][jzm]=a[mo][ha];
                }
            }
        }
        for(int i=n; i>=0; i--) //输出
            if (li[i]) {
                if (i==n) {
                    printf("1
    ");
                    an=2100000000;
                    For(j,1,m) if (an>a[n][j]&&fl[n][j]) an=a[n][j];
                    printf("%d
    ",an);
                    return 0;
                }
                printf("0
    ");
                an=0;
                for(int j=i; j>=1; j--) if (hi[j]!=10000) an++;
                printf("%d
    ",an);
                return 0;
            }
    }
    View Code
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int MAXDP=100000;
    int l[10010],h[10010];
    int dp[10010][1010];
    int x[10010],y[10010];
    bool p[10010];
    int main() {
        int n,i,j,k,m,w;
        scanf("%d%d%d",&n,&m,&k);
        for(i=0; i<n; i++) {
            scanf("%d%d",&x[i],&y[i]);
            l[i]=0;
            h[i]=m+1;
        }
        l[n]=0;
        h[n]=m+1;
        for(i=0; i<k; i++) {
            scanf("%d",&w);
            scanf("%d%d",&l[w],&h[w]);
            p[w]=true;
        }
        for(i=1; i<=n; i++) {
            for(j=0; j<=m; j++) {
                dp[i][j]=MAXDP;
            }
        }
        dp[0][0]=MAXDP;
        for(i=1; i<=m; i++) {
            dp[0][i]=0;
        }
        for(i=1; i<=n; i++) {
            for(j=x[i-1]; j<=m; j++) {
                if(j==m) {
                    for(w=m-x[i-1]; w<=m; w++) {
                        dp[i][j]=min(dp[i][j],dp[i-1][w]+1);
                        dp[i][j]=min(dp[i][j],dp[i][w]+1);
                    }
                }
                dp[i][j]=min(dp[i][j],dp[i-1][j-x[i-1]]+1);
                dp[i][j]=min(dp[i][j],dp[i][j-x[i-1]]+1);
            }
            for(j=max(1,l[i]+1); j<=min(m-y[i-1],h[i]-1); j++) {
                dp[i][j]=min(dp[i][j],dp[i-1][j+y[i-1]]);
            }
            for(j=l[i]; j>=1; j--) {
                dp[i][j]=MAXDP;
            }
            for(j=h[i]; j<=m; j++) {
                dp[i][j]=MAXDP;
            }
        }
        int ans=MAXDP;
        int cnt=k;
        for(i=n; i>=1; i--) {
            for(j=l[i]+1; j<=h[i]-1; j++) {
                ans=min(ans,dp[i][j]);
            }
            if(ans<MAXDP) {
                break;
            }
            if(p[i]==true) {
                k--;
            }
        }
        if(cnt==k) {
            printf("1
    %d",ans);
        } else {
            printf("0
    %d",k);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    poi管道流的导入导出
    Mysql导入数据库的方法
    MySQL数据库指定字符集
    eclipse 的操作
    Mysql的操作
    第十周作业
    第九周作业
    第八周作业
    第七周作业
    第六周作业
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8869769.html
Copyright © 2011-2022 走看看