zoukankan      html  css  js  c++  java
  • [NOIP2014][题解]飞扬的小鸟

    题目链接:https://www.luogu.org/problemnew/show/P1941

    思路:

    预处理x=1的情况。

    先做完全背包再做0/1背包。

    时间复杂度O(n*m),空间复杂度O(n*m).

    其实空间复杂度可以用滚动数组优化成O(m)

    原理同0/1背包和完全背包的优化。

    具体可以看背包9讲。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define R register
    #define ll long long int
    using namespace std;
    const int N=10005,M=1005;
    const int INF=0x3f3f3f3f;
    int n,m,k,up[N],dn[N],l[N],r[N],f[N][M],ans1=INF,ans2,sum[N];//l下  r上
    int main(){
        scanf("%d%d%d",&n,&m,&k);
        for(R int i=0;i<=n-1;i++)
        scanf("%d%d",&up[i],&dn[i]);
        for(R int i=0;i<=n;i++)
        l[i]=1,r[i]=m;
        for(R int i=1;i<=k;i++)
        {
            R int x;
            scanf("%d",&x);
            scanf("%d%d",&l[x],&r[x]);
            l[x]++;r[x]--;
            sum[x]++;
        }
        for(R int i=1;i<=n;i++)
        sum[i]+=sum[i-1];
        memset(f,0x3f,sizeof(f));
        for(R int i=1;i<=m-dn[0];i++)
        if(i<=r[1]&&i>=l[1])f[1][i]=0;
        
        for(R int i=m-dn[0]+1;i<=m;i++)
        if(i>=1+up[0]&&i<=r[1]&&i>=l[1])
        f[1][i]=1;
        
        for(R int i=2;i<=n;i++){
            for(R int j=l[i-1];j<=r[i];j++)
            {    
                if(j==m)
                for(R int k=m-up[i-1];k<=m;k++)
                {    
                    f[i][j]=min(f[i][j],min(f[i-1][k]+1,f[i][k]+1));
                    if(f[i][j]+5000<INF)ans2=sum[i];
                }
                if(j-up[i-1]>0)
                f[i][j]=min(f[i][j],min(f[i-1][j-up[i-1]]+1,f[i][j-up[i-1]]+1));
                if(f[i][j]+5000<INF)  ans2=sum[i];
            }    
            for(R int j=l[i];j<=r[i];j++)
            {
                if(j+dn[i-1]>=l[i-1]&&j+dn[i-1]<=r[i-1])
                f[i][j]=min(f[i][j],f[i-1][j+dn[i-1]]);
                if(f[i][j]+5000<INF)  ans2=sum[i];
            }
            for(R int j=l[i-1];j<l[i];j++)
            f[i][j]=INF;
        }
        for(R int i=1;i<=m;i++)
        ans1=min(ans1,f[n][i]);
        if(ans1<0x3f3f3f3f)
        printf("1
    %d",ans1);
        else printf("0
    %d",ans2);
        return 0;
    }
    //数组越界
    //完全背包更新的范围(假设有东西的区域可以更新)
    //
  • 相关阅读:
    x01.os.17: 换心术
    x01.os.16: 添加功能
    x01.os.15: 看上去很美
    JVM 栈帧之操作数栈与局部变量表
    IDEA字节码学习查看神器jclasslib bytecode viewer介绍
    java上下文Context类
    UML ——区分类图中的几种关系.md
    UML ——六种依赖关系.md
    JDK动态代理[1]----代理模式实现方式的概要介绍
    java方法句柄-----5.Method Handles in Java
  • 原文地址:https://www.cnblogs.com/sky-zxz/p/9905173.html
Copyright © 2011-2022 走看看