zoukankan      html  css  js  c++  java
  • 和菜鸟一起学算法之二分法求极值问题

             ACM,大学最开始接触的,也是让我学到最多的东西,至此还没有忘记。记得当初寒假一个人默默地学习C语言,从变量,从函数。回到学校后,看着同学都在游戏之中,而自己每天默默地切题,有时还比他们还要晚。可是付出了,不一定有回报,比赛是一个团队,不是单靠个人,虽然我们的个人能力是没有问题的,但是,ACM还要靠RP。哈哈。。。总结下,主要还是自己的基础不够扎实,不够深入理解,只是知道这道题目怎么AC了,就草草地结束了,没有总结,没有透彻的吃进去。

             无聊之际,得把以前学的都总结下,为了留下足迹,为了养成学到什么总结什么的好习惯。不是有说男人20几岁就要开始养成写作的习惯嘛。以前学的算法都基本上忘得差不多了,以前放在网易Blog中的一些文章,在此拿出来继续看看,可能会觉得不一样的意境。也可以再次充实下自己。

            关于求极值,很多时候利用数学知识还是可以很好解决的,不过人是懒的,可以不用大脑,就不用了,什么事情都可以让计算机去实现。如果要用数学方法的话,求导还是可以求出最大值,最小值的,不过定义域范围什么的,有时会比较恶心。还是用我们的计算机来实现吧。让计算机来计算极值。

            二分法,其中二分好像比较熟悉吧,对的,二分查找?查找用二分的话,那么时间复杂度可以降低到O(log2n)。不断地去逼近我们要找的那个值。比如已经排序好的

            a[9] = {123456789}

            如果我们要查找6,一般情况下,我们是从123。。。这样慢慢找下去的。不过用二分的话,

                   l=0r=8m=(l+r)/2=4,a[m] = 5

            发现56小,所以应该在m-r这个范围内,接着

                  l=4,   r=8,      m=(l+r)/2=6a[m]=7,

            比较发现76大,所以这个值应该在l-m之间,即a[4]-a[6]之间,然后再次下去,就找到了6。就这么简单。而二分求极值,其实和这个差不多,只是他加进了函数,判断的条件不比较mid这个值和所要找的值。具体来看看下面这道题目吧。

     

    xmu 1214.购物

    Time Limit: 1000 MS         Memory Limit: 65536 K

    Total Submissions: 263 (60 users)         Accepted: 68 (49 users)

    [ My Solution ]

     

    Description

    为了组织班级聚会,wlnwyyfc来到新华都购买一种物品,这类物品的价值为P。他身上有N笔款项,每笔款项都有相应的价值。他希望使用这些款项至少要买M件这类物品,但是款项必须要单独使用,即不能合在一起去购买。问物品的价值P(必须为正整数)最大能为多少?

     

    Input

    第一行输入两个整数N(1<=N<=100,000)M(1<=M<=1,000,000,000)

    接下来输入N个正整数ai(1<=ai<=1,000,000,000),表示N笔款项的价值。

     

    Output

    输出一个数,表示P的最大值。如果没有满足的值,输出-1

     

    Sample Input

    3 4

    10 5 2

     

    Sample Output

    3

     

    Source

    wlnwyyfc@xmu

     

    这个题目就是对价值p进行二分求最大值

    #include <stdio.h>
    
    int main()
    
    {
    
     int n, m, a[100001], i, sum = 0;
    
     scanf("%d%d", &n, &m);
    
     for(i = 0; i < n; i++)
    
     {
    
      scanf("%d", &a[i]);
    
      if(sum < a[i]) sum = a[i];//先求出最大的款项
    
     }
    
     int l = 1, r = sum, mid; 最大的价值p肯定是1到这最大的款项之间。
    
     while(1)           //下面也可以算作是二分的框架吧
    
     {
    
      mid = (l + r) / 2;
    
      int cnt = 0;
    
      for(i = 0; i < n; i++)                        
    
       cnt += a[i] / mid;         //表示最多可以买的件数
    
      if(l >= r-1)            //这里表示已经二分完了
    
      {
    
       if(cnt >= m){printf("%d\n", mid); break;}        //表明有这个最大值
    
       else {printf("-1\n"); break;}
    
      }
    
      if(cnt >= m)l = mid;                这个和二分查找没什么区别吧?
    
      else if(cnt < m) r = mid;
    
     }
    
    return 0;
    
    }
    
    

     

            二分还是比较简单的,因为我们都学过二分查找,也就是折半查找,不过还有三分法,哈哈,这个三分法一开始我还没有十分明白。到点吃饭了,唉,通货膨胀,物价就这么涨了,吃个饭也这么贵。吃完再来分析分析三分法求极值问题吧。。。。

  • 相关阅读:
    Tomcat起不来的原因
    Memcache和memcached
    charles
    chrome 和 chromeDriver
    解决Establishing SSL connection without server‘s identity verification is not recommended.
    Shiro的认证与授权
    详解 TCP的三次握手四次挥手
    计算机网络-第三章-数据链路层笔记总结
    阿里云高校计划续用考试凉凉
    用管程解决生产者消费者问题
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300090.html
Copyright © 2011-2022 走看看