Interviewe HDU - 3486
原题链接
考察:枚举+RMQ
错误思路:
二分+RMQ,这里不能二分的原因是不能整除的时候,后面超出的是舍弃,舍弃部分可能会使二分答案没有单调性.
正确思路:
枚举答案,但需要优化,假设每段都可以取到最大值,那么\(>k\)最少需要\(\frac {k+maxn-1}{maxn}\).然后判断是否可行
Code
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 200010,M = 17;
int n, k,w[N],f[N][M],ans[N];
bool check(int mid)
{//分成3个面试官:取3个人
int len = n / mid, sum = 0;
int c = log(len) / log(2);
int cnt = 0;
for (int i = 1; i <= n;)
{
int r = i + len - 1;
if(r>n) break;
ans[++cnt] = max(f[i][c],f[r-(1<<c)+1][c]);
i = r + 1;
}
sort(ans+1,ans+cnt+1);
for(int i=cnt;i>=cnt-mid+1;i--)
sum+=ans[i];
return sum > k;
}
void init()
{
memset(f,0,sizeof f);
for (int j = 0; j < M;j++)
for (int i = 1; i+ (1<<j)-1 <= n;i++)
if(!j)
f[i][j] = w[i];
else
f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF&&n!=-1)
{
int maxn = 0,st = 1,ans = -1;
for (int i = 1; i <= n;i++) scanf("%d", &w[i]),maxn = max(w[i],maxn);
init();
if(maxn) st = (k+maxn-1)/maxn;
for(int i = st;i<=n;i++)
{
if(check(i))
{
ans = i;
break;
}
}
printf("%d\n",ans);
}
return 0;
}