您的位置:首页 > 其它

HDU 3486

2014-03-11 21:58 253 查看
题意:n个人来应聘,可以把他们分为m组,每组n/m个人,多出来的人不要了,每组录取一个人,录取的人的权值之和必须大于k,求最小的m

分析:RMQ,从小到大枚举m,判断是否满足要求,在枚举之前计算一下和要大于k至少要分成多少组(否则会超时)

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#define N 200005
using namespace std;
int d
[25],v
;
void RMQ_init(int n){
    int i,j;
    for(i=1;i<=n;i++)
    d[i][0]=v[i];
    for(j=1;(1<<j)<=n;j++){
        for(i=1;i+(1<<j)-1<=n;i++)
        d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
    }

}
int RMQ(int L ,int R){
   //  int k=(int)(log((R-L+1)*1.0)/log(2.0));
   int k=0;
   while((1<<(k+1))<=R-L+1)
   k++;
    return max(d[L][k],d[R-(1<<k)+1][k]);
}
int main()
{
    int t,n,k,m,i,j,p,ans;
    while(~scanf("%d%d",&n,&k)){
        if(n<0&&k<0)
        break;
        for(i=1;i<=n;i++)
        scanf("%d",&v[i]);
        RMQ_init(n);
        int tmp=RMQ(1,n);
        for(m=max(1,(k+1)/tmp);m<=n;m++){
           //每组t个人,分成m组
          t=n/m;
            ans=0;
            for(p=0,j=1;p<m;p++,j+=t){ //终止条件改成j<=n会超时
                ans+=RMQ(j,j+t-1);
                if(ans>k)
                break;
            }
            if(ans>k)
            break;
        }
        if(m<=n)
        printf("%d\n",m);
        else
        printf("-1\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: