二分答案——简单题

一、何时可以使用“二分答案”

    不是任何题目都适合使用“二分答案”的,我Sam观察到一般有以下的一些特征:


    A. 候选答案必须是离散的 ,且已知答案的范围是:[最小值min, 最大值max] (连续区间上不能进行二分操作)

 

        例如,在题目“Kth Largest 第k大的数”中 ==> 答案是闭区间[a[1]b[1], a[n]b[n]]上的正整数
        例如,在题目“Drying 烘干衣服”中 ==> 烘干时间t∈[0,maxT], maxT=max{a[i]}


    B. 候选答案在区间[min,max]上某种属性一类一类的排列 (这样就能在此属性上进行二分操作 ),各个类别不交错混杂

 

        例如,在题目“Kth Largest 第k大的数”中 ==>

                 (候选答案)第k大的数的值:              a[1]b[1],  ... , a[n]b[n]

                 (属性分类)>这个乘积的数有多少:      n^2-1     ...      0

 

        例如,在题目“Drying 烘干衣服”中 ==>

                 (候选答案)烘干时间:  t=0,  t=1,  t=2,  t=3,  ...,  t=maxT-1,  t=maxT

                 (属性分类)能否烘干:  不能  不能   不能   能     ...    能               能


    C. 容易判断某个点 是否为答案(即二分过程中,mid指向的点是否为答案)
        例如,在题目“Kth Largest 第k大的数”中 ==> λ∈[ a[1]b[1], a[n]b[n] ]

                 对于某个候选答案,如果“>λ的乘积个数"<k   && “>λ-1的乘积个数”≥k ,则答案为λ

 

        例如,在题目“Drying 烘干衣服”中 ==>

                 需要寻找第一个出现的“能”(true),即如果check(mid-1)==false && check(mid)==true ,则答案为mid.

【题目描述】:输入n个数(0<n<=200000),把n个数分成m部分(0<m<=1000)求分出的最小值最大是多少

代码:

 1 #include<cstdio>
 2 #include<cstdio>
 3 
 4 using namespace std;
 5 
 6 #define N 200000+100
 7 
 8 int n,m,sum;
 9 int a[N];
10 
11 bool found(int k)
12   {
13       int p=0,ans=0;
14       for(int i=1;i<=n;i++)
15         {
16             p+=a[i];
17             if(p>=k) ans++;
18             if(ans>m) return 0;
19         }
20     return 1;
21   }
22 
23 int main()
24   {
25       scanf("%d%d",&n,&m);
26       for(int i=1;i<=n;i++)
27         scanf("%d",&a[i]),sum+=a[i];
28       int l=0,r=sum;
29       while(l<=r)
30         {
31             int mid=(l+r)/2;
32             if(found(mid)) r=mid-1;
33             else           l=mid+1;
34         }
35     printf("%d",l-1);
36       return 0;
37   }

 

转载于:https://www.cnblogs.com/yuemo/p/5521483.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值