hdu 3486

题意: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;
}
原文地址:https://www.cnblogs.com/linhaitai/p/9791479.html