1. 程式人生 > >CF1066D Boxes Packing(二分答案)

CF1066D Boxes Packing(二分答案)

return pre 就是 當前 scan () 二分答案 amp iostream

題意描述:
你有$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$先生能放入盒子裏的最多的物品數量

思路:

水題。。。

因為他挑選的規則一定,而刪除的方式一定,所以,答案擁有單調性。

單調性:因為有一個最大合法點,在那之後都是合法的,所以再往後走的話,答案一定越來越小

所以我們的目的就是找這個最大合法點。

怎麽找呢?

因為挑選方式一定,所以合法性可以O(n)驗證。

這樣的話,很顯然就可以用一個東西叫二分答案

二分合法點就好了qwq

代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rii register int i
#define
rij register int j using namespace std; int n,m,k; int a[200005]; bool check(int wz) { int now=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; } int main() { scanf("%d%d%d",&n,&m,&k); for(rii=1;i<=n;i++) { scanf("%d",&a[i]); } int l=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; } } int mid=(l+r)/2; if(check(mid)==true) { r=mid; } else { l=mid; } } printf("%d",n-l+1); }

CF1066D Boxes Packing(二分答案)