zoukankan      html  css  js  c++  java
  • luogu_ P1941 飞扬的小鸟

    传送门:https://www.luogu.org/problem/P1941

    关于此题,只能说细节吧。

    1. 一次可以按很多次。随意转移时可以运用完全背包的思想,在这里你不能因为某个状态不合法就直接否了,因为他只是不能像下一列转移,我们需要用它对同一列转移
    2. 对于超过m的高度要格外注意,不要漏掉情况。
    3. n和m不能搞反啊......
    4. 对于第1点,你要确认你所用的转移点不是经过下降得来的。关于这一点你可以在更新下一列状态的同时做完全背包,因为完全可以保证下一列的同一高度绝对不会是下降得来(至今没有比它高的呢。

    然后转移方程什么的,就很显然了。初始状态f[0][0]记得赋值为极大值,那个状态是不合法滴!

    //代码真心丑,费时有点长。。。。。
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define R register
    using namespace std;
    int n,m,k,ans=1e9,du[11000],dd[11000],s[11000],up[11000],down[11000],f[11000][1100];
    int main (){
        scanf("%d%d%d",&n,&m,&k);
        for(R int i=0;i<n;i++){
            scanf("%d%d",&du[i],&dd[i]);
            up[i]=m;down[i]=1;
        }
        up[n]=m;down[n]=1;
        for(R int x,i=1;i<=k;i++){
            scanf("%d",&x);
            s[x]++;
            scanf("%d%d",&down[x],&up[x]);
            down[x]++;
            up[x]--;
        }
        for(R int i=1;i<=n;i++) s[i]+=s[i-1];
        memset(f,0x3f,sizeof(f));
        for(R int i=1;i<=m;i++) f[0][i]=0;
        for(R int i=0;i<n;i++){
            for(R int j=1;j<=m;j++){
                f[i+1][(j+du[i]>m?m:j+du[i])]=min(f[i+1][(j+du[i]>m?m:j+du[i])],f[i+1][j]+1);
                if(j>=down[i]&&j<=up[i]){
                    if(f[i][j]<1e9) f[i+1][j+du[i]>m?m:j+du[i]]=min(f[i+1][j+du[i]>m?m:j+du[i]],f[i][j]+1);
                    if(f[i][j]<1e9&&j-dd[i]>=down[i+1]&&j-dd[i]<=up[i+1]) f[i+1][j-dd[i]]=min(f[i+1][j-dd[i]],f[i][j]);
                }
                else{
                    f[i][j]=f[10100][1010];
                }
            }
        }
        for(R int i=1;i<=m;i++){
            if(i>=down[n]&&i<=up[i]) ans=min(ans,f[n][i]);
            else f[n][i]=f[10100][1010];
        }
        if(ans<1e9){
            printf("1
    %d
    ",ans);
        }
        else{
            printf("0
    ");
            for(R int i=n-1;i>=1;i--){
                for(R int j=1;j<=m;j++){
                    if(f[i][j]<1e9){
                        printf("%d
    ",s[i]);
                        exit(0);
                    }
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    正则表达式练习
    Linux下文件删除的原理
    (转)linux grep 正则表达式
    linux 需要记忆的知识
    linux 常用命令
    TestNG测试方法
    TestNG配置注解
    jquery 获取和设置 select下拉框的值
    Kings(状压DP)
    Tirp(状压DP)
  • 原文地址:https://www.cnblogs.com/coclhy/p/11731336.html
Copyright © 2011-2022 走看看