codeforces883I,二分+单调性 思想是dp的思想

此题就是要注意单调性

每到一个点就要更新这个点是否是 isable[]代表以这个点前的所有组是否能成我们要求的一些组

islead[]代表包括这个点以及这个点是否能成我们要求的一些组

然后就二分答案

每次检查islead[n]就好了

然后注意ablel是有单调性的这样就是nlogn了否则我们要nlogn*logn来做了

还看不懂的朋友阔以留言~~~~

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int isable[300020],islead[300020];
int v[300020];
int n,k;
int ablel;
bool isleadd(int limit,int num)
{
    if(num>=k&&v[num]-v[1]<=limit)//前面只有一个组
       {
          if(ablel==-1)
            ablel=num+1;
         return true;
       }
      if(ablel!=-1)//如果不能保证只有一组我们就考虑多组了
      {
        while(num-ablel+1>=k)
           {
               if(isable[ablel]&&v[num]-v[ablel]<=limit)
                return true;
               ablel++;
           }
      }
      return false;//多组都没有就false了
}
bool solve(int limit)
{
    for(int i=1;i<=n;i++)
    {
        if(isleadd(limit,i))
            islead[i]=1;
        if(islead[i-1])
            isable[i]=1;
    }
    if(islead[n])
        return true;
    else
        return false;
}
int main()
{
    scanf("%d%d",&n,&k);
    ablel=-1;
    int minn=1000000020;
    int maxx=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&v[i]);
        maxx=max(maxx,v[i]);
        minn=min(minn,v[i]);
    }
    sort(v+1,v+1+n);
   if(k!=1)
     {
         int l=0;
         int r=maxx-minn;
         while(l<r)
         {
            // cout<<"l:"<<l<<" "<<"r;"<<r<<endl;
             int mid=(l+r)>>1;
             if(solve(mid))
                r=mid;
             else
                l=mid+1;
                for(int i=1;i<=n;i++)
                {
                    isable[i]=0;
                    islead[i]=0;
                }
                ablel=-1;
         }
         printf("%d\n",r);
     }
     else
        printf("0\n");
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值