zoukankan      html  css  js  c++  java
  • [NOIP2014TG] 洛谷 P1941 飞扬的小鸟

    分析题意,可以发现:按屏幕的过程类似于“取”与“不取”,柱子则是一些“限制条件”和“范围”。

    思路

    首先明确:

    1、一秒可以无限点上升键(完全背包),并且一旦上升就不会下降Y。

    ​ 一秒只能下降一次,不用点(01背包)。

    2、碰到地面会死(处理下降时),碰到天花板不会死(处理上升时)

    (f[i][j])为在第i列时,所处高度为i可行的最少点击屏幕数。

    分段进行状态转移:(手打公式好累啊)

    ( f[i][j]=min (f[i][j-X[i]]+1,f[i-1][j-X[i]]+1)quad(X[i]+1leq jleq m+X[i]))

    //可以按一次(01),也可以按两次以上(完全)。碰到天花板不会死,所以还要更新([m+1,m+X[i]])的状态。

    (f[i][j]=min(f[i][j],f[i][m])quad (m+1leq jleq m+X[i]))

    //([m+1,m+X[i]])范围内的状态效果与(f[i][m])(正好跳到天花板)相同。如果正好跳到天花板更优则更新。

    ( f[i][j]=min(f[i][j],f[i-1][j-Y[i])quad (1leq jleq m-Y[i]))

    //01背包,从(Y[i])单位长度上方掉落。

    $ Inf quad (jleq L[i],H[i]leq j)$

    //到不了的,碰到柱子的设为(Inf)

    代码

    #include<iostream>
    #include<iomanip>
    #include<cmath>
    using namespace std;
    const int maxn=10005,maxm=2005;
    int f[maxn][maxm],L[maxn],H[maxn],X[maxn],Y[maxn];
    int n,m,k,p,cnt,ans,temp;
    bool flag;
    
    int main()
    {
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++)
            cin>>X[i]>>Y[i],L[i]=0,H[i]=m+1;//没有柱子也要设置上下界
        for(int i=1;i<=k;i++)
            cin>>p,cin>>L[p]>>H[p];
        for(int i=1;i<maxn;i++)
         	for(int j=1;j<maxm;j++)
         		f[i][j]=114514;
         //输入,设初值
        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);//可以按一次(01),也可以按两次以上(完全)。碰到天花板不会死,所以还要更新[m+1,m+X[i]]的状态。
            for(int j=m+1;j<=m+X[i];j++)
                f[i][m]=min(f[i][j],f[i][m]);//[m+1,m+X[i]]范围内的状态效果与f[i][m](正好跳到天花板)相同。如果正好跳到天花板更优则更新。
            for(int j=1;j<=m-Y[i];j++)
             	f[i][j]=min(f[i][j],f[i-1][j+Y[i]]);//01背包,从$Y[i]$单位长度上方掉落。
            
            for(int j=1;j<=L[i];j++) f[i][j]=114514;
            for(int j=H[i];j<=m;j++) f[i][j]=114514;
            //到不了的,碰到柱子的设为Inf
        }
        ans=114514;
        for(int i=1;i<=m;i++)
            ans=min(ans,f[n][i]);
        if(ans<114514)
            cout<<1<<"
    "<<ans;
        else {
            cout<<"0
    ";
            cnt=0;
            for(int i=n;i>=0;i--)
            {
                for(int j=1;j<=m;j++)
                    if(f[i][j]<114514)
                    {
                        flag=1;
                        break;//从后往前搜,一旦有一处能到达,就说明这之前的柱子都能通过
                    }
                if(flag)
                {
                    cnt=i;
                    break;
                }
            }
            for(int i=1;i<=cnt;i++)
                if(H[i]<=m) temp++;//统计柱子数
            cout<<temp;
        }
        return 0;
    }
    

    注:数据范围允许使用【数据删除】作为Inf使用


  • 相关阅读:
    (转) hive调优(2)
    (转)hive调优(1) coding调优
    hive on tez 错误记录
    tez 0.9.0 配置
    hive on tez
    让博客园自动生成目录
    hive --metastore三种模式
    hive 使用beelin连接报错
    mysql my.cnf文件
    1、Kfaka 部署
  • 原文地址:https://www.cnblogs.com/ehznehc/p/10985000.html
Copyright © 2011-2022 走看看