题意:n个人,每个人的价格a[ i ] ,求最少分几组,每组取一个人,多出来的人就不考虑,使得这取出人的价格大于k。(每组人数一样)
分析:每组取一个人,那这个人肯定是这组最大的,枚举多少组就可以了。
代码:
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> using namespace std; typedef long long ll; const int max_=2e5+1; int dp[max_][20],a[max_]; void ST_init(int n) { for(int i=1;i<=n;i++) { dp[i][0]=a[i]; } for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1<=n;i++) { dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); } } int ST_que(int L,int R) { int k=0; while((1<<(k+1))<=R-L+1)k++; return max(dp[L][k],dp[R-(1<<k)+1][k]); } int main() { int n; ll k; while(~scanf("%d %lld",&n,&k)) { if(n==-1||k==-1) break; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } ST_init(n); int maxm=ST_que(1,n);//求最大 // printf("%lld ",maxm); int maxn=(k+1)/maxm;//看看最少多少组 int m=max(1,maxn); for(;m<=n;m++) { ll ans=0; int t=n/m;//每一组的长度 for(int j=1,p=0;p<m;p++,j+=t) { ans+=ST_que(j,j+t-1);//加最大值 if(ans>k) break;//跳出 } if(ans>k) break;//跳出 } if(m<=n) printf("%d ",m); else printf("-1 "); } return 0; }