CF1066D Boxes Packing

Posted smyjr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

以上是关于CF1066D Boxes Packing的主要内容,如果未能解决你的问题,请参考以下文章

D. Boxes Packing

903C. Boxes Packing#俄罗斯套娃问题(map使用)

CF821C Okabe and Boxes

CF1030F Putting Boxes Together

CF768F Barrels and boxes

CF821 C. Okabe and Boxes 栈模拟