HDU 3486
2014-03-11 21:58
253 查看
题意:n个人来应聘,可以把他们分为m组,每组n/m个人,多出来的人不要了,每组录取一个人,录取的人的权值之和必须大于k,求最小的m
分析:RMQ,从小到大枚举m,判断是否满足要求,在枚举之前计算一下和要大于k至少要分成多少组(否则会超时)
分析: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; }
相关文章推荐
- 第2周:Java事件处理
- 挨踢之路之学习流程篇(七)
- poj3096 Surprising Strings
- List,Set,Map用法以及区别
- 周易正易 p499-599
- 【原理】Histograms of Oriented Gradients (HOG)理解
- Django+Mysql的安装
- 文本特征提取方法研究
- hdu2489 Minimal Ratio Tree
- Windows平台下LispBox环境搭建
- 黑马程序员09_IO
- 取得表中数据的insert语句
- 关于struts、spring 和 hibernate的说明
- fgets()
- 【贪心算法】喷水装置
- iOS 应用程序的生命周期
- css滑动门实现
- c/c++ 100行代码破解winrar
- Get与Post的区别
- System Center 2012R2之SCOM监控SQL DB服务器系统