放牛奶的冰箱(二分答案)
题目描述
冬冬在古子城购买了一台冰箱,冰箱内部可以表示为高度为h,深度为1,宽度为2的矩阵,最初冰箱底部只有一个架子,但冬冬可以在任何一个格子顶部放隔板,隔板的宽为2,不占用任何空间,将冰箱内部分隔成上、下两部分。
冬冬有n瓶牛奶要按顺序放入冰箱里。第i瓶牛奶的高度是ai,深度和宽度均为1。如果架子上方的相应空间至少与瓶子一样高,他可以在一个架子上放一瓶牛奶,他不能将两瓶牛奶叠在一起(如果它们之间没有架子)。
冬冬有n瓶牛奶要按顺序放入冰箱里。第i瓶牛奶的高度是ai,深度和宽度均为1。如果架子上方的相应空间至少与瓶子一样高,他可以在一个架子上放一瓶牛奶,他不能将两瓶牛奶叠在一起(如果它们之间没有架子)。
上图为一个高为7,宽为2的冰箱,在高为5的位置放了一块隔板,冰箱内放了高3瓶牛奶,高度为3、5、2。
冬冬按顺序将牛奶往冰箱里放,他最多能往冰箱里放k瓶牛奶,他想知道k的值为多少?
输入
第一行包含两个整数n和h(1≤n≤10
6,1≤h≤10
6)表示牛奶的数量和冰箱的高度。
第二行包含n个整数a1,a2,…,an(1≤ai≤min(100,h))表示第i瓶牛奶的高度。
第二行包含n个整数a1,a2,…,an(1≤ai≤min(100,h))表示第i瓶牛奶的高度。
输出
输出k的值。
样例输入 Copy
【样例1】
5 7
2 3 5 4 1
【样例2】
10 10
9 1 1 1 1 1 1 1 1 1
【样例3】
5 10
3 1 4 2 4
样例输出 Copy
【样例1】
3
【样例2】
4
【样例3】
5
提示
对于60%的数据,1≤n≤1000,1≤h≤1000,1≤ai≤min(100,h)。
对于100%的数据,1≤n≤10 6,1≤h≤10 6,1≤ai≤min(100,h)。
思路:二分答案。二分后,对1-mid的数排序,从大到小,h-a[i],i+=2;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;
#define rep(i , a , b) for(register int i=(a);i<=(b);i++)
#define per(i , a , b) for(register int i=(a);i>=(b);i--)
#define ms(s) memset(s, 0, sizeof(s))
#define squ(x) (x)*(x)
#define first fi
#define second se
#define iterator iter
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int , int> pi;
typedef unordered_map<int,int> un_map;
typedef priority_queue<int> prque;
template<class T>
inline void read (T &x) {
x = 0;
int sign = 1;
char c = getchar ();
while (c < '0' || c > '9') {
if ( c == '-' ) sign = - 1;
c = getchar ();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar ();
}
x = x * sign;
}
const int maxn = 1e6 + 10;
const int inf = 1e9;
const ll INF = ll(1e18);
const int mod = 998244353;
const double PI = acos(-1);
//#define LOCAL
int n,h;
int a[maxn];
int b[maxn];
bool cmp(int x,int y) {
return x>y;
}
bool check(int x) {
rep(i,1,x) b[i]=a[i];
sort(b+1,b+1+x,cmp);
int ans = 0;
for(int i=1;i<=x;i+=2) {
ans+=b[i];
}
if(ans<=h) return 1;
return 0;
}
void solve() {
read(h);
rep(i,1,n) read(a[i]);
int l = 0,r = n;
int ans = 0;
while(l<r) {
int mid = (l+r)>>1;
if(check(mid)) {
ans=max(ans,mid);
l=mid+1;
}
else r=mid;
}
printf("%d\n",ans);
}
int main(int argc, char * argv[])
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
while(~scanf("%d",&n)) {
solve();
}
return 0;
}