题意描述:你有$n$个物品,每个物品大小为$a_i$,$m$个盒子,每个盒子的容积为$k$。$Maksim$先生想把物品装入盒子中。对于每个物品,如果能被放入当前的盒子中,则放入当前盒子,否则换一个新的盒子放入。为了放入尽可能多数量的物品,$Maksim$先生会从左开始扔掉一部分物品。现在,$Maksim$先生想知道,他最多能放入盒子多少物品输入输出格式:输入格式:第一行,三个整数$n$,$m$,$k$,$(1≤n,m≤2 \times 10^5$,$ 1≤k≤10^9)$含义参见上文第二行,$n$ 个数,第$i$表示$a_i$输出格式:一行,一个数,表示$Maksim$先生能放入盒子里的最多的物品数量
Ideas:
Water problem ...
Because the rules he picks are certain, and the way to delete them must be, so the answer has monotonicity.
Monotonicity: Because there is a maximum legal point, after that is legal, so go back again, the answer must be getting smaller
So our goal is to find the biggest legal point.
How to find it?
Because the selection method is certain, legitimacy can be verified by O (n).
In that case, it's obvious that you can call a two-point answer.
The two points are legal. Qwq
Code:
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#defineRii Register int i#defineRij Register Int Jusing namespacestd;intn,m,k;inta[200005];BOOLCheckintwz) { intnow=0, cnt=1; for(rii=wz;i<=n;i++) { if(a[i]>k) {return false; } if(now+a[i]>k) { now=0; CNT++; } Now+=A[i]; } if(cnt>m) {return false; } return true;}intMain () {scanf ("%d%d%d",&n,&m,&k); for(rii=1; i<=n;i++) {scanf ("%d",&A[i]); } intL=1, r=N; while(l<r) {if(r-l==1) { if(check (l) = =true) { Break; } Else { if(check (r) = =true) {L=R; } Else{L=n+1; } Break; } } intMid= (L+R)/2; if(check (mid) = =true) {R=mid; } Else{L=mid; }} printf ("%d", n-l+1);}
cf1066d Boxes Packing (two-point answer)