• CF1066D Boxes Packing


    传送门

    这题为什么要用二分呢?/huaji

    首先可以(O(n))预处理出从某个物品(i)开始放,只放一个盒子,能放的最后物品的位置(j),只要用两个指针维护左右端点,每次移动一下左端点同时尽量把右端点右移救星了

    然后我们要放的所有物品是原来的一个后缀,所以要从后往前放,但是直接贪心放是错的.考虑构建一棵树,根据前面对每个(i)预处理出的(j),连((j+1,i))的单向边,然后从(n+1)开始dfs,记(n+1)的深度为0,那么我们不能访问深度大于(m)的点.记能访问到最小的点为(y),答案为(n-y+1)

    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define db double
    #define eps (1e-5)
    
    using namespace std;
    const int N=200000+10;
    il LL rd()
    {
        LL x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int to[N],nt[N],hd[N],tot=1;
    il void add(int x,int y){++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;}
    int n,m,k,a[N],ans,tt=-1;
    il void dfs(int x)
    {
      ++tt;
      ans=max(ans,n-x+1);
      if(tt<m) for(int i=hd[x];i;i=nt[i]) dfs(to[i]);
      --tt;
    }
    
    int main()
    {
      n=rd(),m=rd(),k=rd();
      for(int i=1;i<=n;i++) a[i]=rd();
      for(int i=1,su=a[1],j=1;i<=n;i++)
        {
          while(j<n&&su+a[j+1]<=k) su+=a[++j];
          add(j+1,i),su-=a[i];
        }
      dfs(n+1);
      printf("%d
    ",ans);
      return 0;
    }
    
    
    
  • 相关阅读:
    SVN资料库转移-----dump和load
    windows Server 2003修改远程连接限制
    oracle定时任务
    Oacle常用语句
    决策树
    Logistic回归
    Matplotlab绘图基础
    基本术语
    看懂执行并优化
    数据分析方法论
  • 原文地址:https://www.cnblogs.com/smyjr/p/9822262.html
Copyright © 2020-2023  润新知