• 【洛谷】 P1941 飞扬的小鸟 (题解)


    题目链接

    这题关于DP

    用f[i][j]表示横坐标为i时高度为j的最少点击次数。

    用正无穷来表示不可能达到这个状态。

    于是我们可以分析出状态转移的方式:

    上升——完全背包转移方式

    下降——01背包转移方式

    超过m变为m——特判

    细节详见代码

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int maxx=100000;
    int l[10010],h[10010];
    int f[10010][1010];
    int x[10010],y[10010];
    bool p[10010];
    int main()
    {
        int n,i,j,k,m,w;
        cin>>n>>m>>k;
        for(i=0;i<n;i++)
        {
            cin>>x[i]>>y[i];
            l[i]=0;
            h[i]=m+1;
        }
        l[n]=0;
        h[n]=m+1;
        for(i=0;i<k;i++)
        {
            cin>>w;
            cin>>l[w]>>h[w];
            p[w]=true;
        }
        for(i=1;i<=n;i++)
        {
            for(j=0;j<=m;j++)
            {
                f[i][j]=maxx;
            }
        }
        f[0][0]=maxx;
        for(i=1;i<=m;i++)
        {
            f[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++)
                    {
                        f[i][j]=min(f[i][j],f[i-1][w]+1);
                        f[i][j]=min(f[i][j],f[i][w]+1);
                    }
                }
                f[i][j]=min(f[i][j],f[i-1][j-x[i-1]]+1);
                f[i][j]=min(f[i][j],f[i][j-x[i-1]]+1);
            }
            for(j=max(1,l[i]+1);j<=min(m-y[i-1],h[i]-1);j++)
            {
                f[i][j]=min(f[i][j],f[i-1][j+y[i-1]]);
            }
            for(j=l[i];j>=1;j--)
            {
                f[i][j]=maxx;
            }
            for(j=h[i];j<=m;j++)
            {
                f[i][j]=maxx;
            }
        }
        int ans=maxx;
        int cnt=k;
        for(i=n;i>=1;i--)
        {
            for(j=l[i]+1;j<=h[i]-1;j++)
            {
                ans=min(ans,f[i][j]);
            }
            if(ans<maxx)
            {
                break;
            }
            if(p[i]==true)
            {
                k--;
            }    
        }
        if(cnt==k)
        {
            cout<<"1"<<endl<<ans;
        }
        else
        {
            cout<<"0"<<endl<<k;
        }
        return 0;
    }
    
  • 相关阅读:
    建设是为“有” 共享是为“无”
    设计模式-命令模式
    设计模式-建造者模式
    设计模式-抽象工厂模式(升级版工厂方法模式)
    设计模式-原型模式
    设计模式-单例模式
    Java中的多维数组
    设计模式-装饰者
    设计模式-模板方法
    乐观锁与悲观锁
  • 原文地址:https://www.cnblogs.com/BorisDimitri/p/13546616.html
Copyright © 2020-2023  润新知