zoukankan      html  css  js  c++  java
  • luogu 1941 飞扬的小鸟

    这道题对于第13个数据点,不知为什么f数组第二位开到2000以下就不能过,求指教

    飞扬的小鸟

    传送门

    题目大意

    一个小鸟在(n*m)的方阵里,然后有许多管道你们玩过就不多介绍了,然后每一个位置,点击会上升,不点击可以下降,点击效果可以叠加。
    求如果通关的最小点击次数,否则会最多通过多少个管道。

    solution

    30pts

    就是搜索,本以为会拿50pts。

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <cstdio>
    using namespace std;
    int n,m,k,up[20000],down[20000],vis[20000],flag,maxn,minn=0x7fffffff;
    struct edge {
        int u,d;
    } e[20000];
    void dfs(int x,int h,int tot) {
        if(h<=0) return ;
        maxn=max(maxn,x);
        if(x==n+1 && h>0) {
            flag=true;
            minn=min(minn,tot);
            return;
        }
        if(vis[x+1]) {
            for(int i=1; i<=3; i++) {
                if(h+up[x]*i<e[x+1].u && h+up[x]*i>e[x+1].d )dfs(x+1,((h+up[x]*i<=m)?(h+up[x]*i):m),tot+i);
            }
            if(h-down[x]<e[x+1].u && h-down[x]>e[x+1].d ) dfs(x+1,h-down[x],tot);
        } 
        else {
            for(int i=1; i<=3; i++) {
                dfs(x+1,((h+up[x]*i)<=m?(h+up[x]*i):m),tot+i);
            }
            dfs(x+1,h-down[x],tot);
        }
    }
    int main() {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0; i<=n-1; i++)
            scanf("%d%d",&up[i],&down[i]);
        for(int i=1; i<=k; i++) {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            vis[a]=1;
            e[a].u=c;
            e[a].d=b;
        }
        for(int i=0; i<=m; i++)
            if(vis[i] && i>e[i].d && i<e[i].u)
                dfs(0,i,0);
            else dfs(0,i,0);
        if(flag==true) {
            printf("1
    %d",minn);
        } else {
            int ans=0;
            for(int i=0; i<=maxn; i++)
                if(vis[i])ans++;
            printf("0
    %d",ans);
        }
        return 0;
    }
    

    100pts

    动态规划

    这道题如果细想,还真是可以用背包做,虽然限制条件多了一点。

    如果小鸟向上飞,则是完全背包。
    如果小鸟向下飞,则是01背包。
    如果小鸟遇到柱子,那么将此状态取消
    如果小鸟飞到m以上,那么定为m。

    最后输出倒叙查询dp数组就可以了

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int f[10010][2010];
    int n,m,k;
    int x[10010],y[10010];
    int vis[10010];
    int low[10010],high[10010];
    int main() {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1; i<=n; ++i) scanf("%d%d",&x[i],&y[i]);
        for(int i=1; i<=n; ++i) low[i]=1,high[i]=m;
        for(int i=1; i<=k; ++i) {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            vis[a]=1;
            low[a]=b+1;
            high[a]=c-1;
        }
        memset(f,0x3f,sizeof(f));
        for(int i=1; i<=m; ++i) f[0][i]=0;
        for(int i=1; i<=n; ++i) {
            for(int j=x[i]+1; j<=m+x[i]; ++j)
                f[i][j]=min(f[i-1][j-x[i]]+1,f[i][j-x[i]]+1);//如果向上飞
            for(int j=m+1; j<=m+x[i]; ++j)//将超过m的更新到m
                f[i][m]=min(f[i][m],f[i][j]);
            for(int j=1; j<=m-y[i]; ++j)//如果向下飞
                f[i][j]=min(f[i][j],f[i-1][j+y[i]]);
            for(int j=1; j<low[i]; ++j)//遇到柱子直接g
                f[i][j]=f[0][0];
            for(int j=high[i]+1; j<=m; ++j)
                f[i][j]=f[0][0];
        }
        int ans=f[0][0];
        for(int j=1; j<=m; ++j)
            ans=min(ans,f[n][j]);
        if(ans<f[0][0]) printf("1
    %d",ans);
        else {
            int i,j;
            for(i=n; i>=1; i--) {
                for(j=1; j<=m; ++j)
                    if(f[i][j]<f[0][0]) break;
                if(j<=m) break;
            }
            ans=0;
            for(int p=1; p<=i; ++p)
                if(vis[p])ans++;
            printf("0
    %d",ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    jquery toggle(listenerOdd, listenerEven)
    struts quick start
    hdu 1518 Square (dfs)
    hdu 2544 最短路 (最短路径)
    hdu 1754 I Hate It (线段树)
    hdu 1856 More is better (并查集)
    hdu 1358 Period (KMP)
    hdu 2616 Kill the monster (DFS)
    hdu 2579 Dating with girls(2) (bfs)
    zoj 2110 Tempter of the Bone (dfs)
  • 原文地址:https://www.cnblogs.com/ifmyt/p/9675568.html
Copyright © 2011-2022 走看看