• 『嗨威说』算法设计与分析


    本文索引目录:

    一、分治算法的基本思想

    二、一道二分题点拨分治思想

    三、结对编程小结

    一、分治算法的基本思想:

      1.1  基本概念:

      “分而治之”( Divide and conquer)方法 (在ACM玩家中还有一种说法叫 分治术) ,是追求高效算法中常用的一种算法思想。

      所谓“分而治之” 就是把一个复杂的算法问题按一定的“分解”方法分为等价的规模较小的若干部分,然后逐个解决,分别找出各部分的解,把各部分的解组成整个问题的解,这种朴素的思想来源于人们生活与工作的经验,也完全适合于技术领域。

     

      1.2  使用条件:

      (1)问题规模当缩小到某种规模时易于解决的状态。

      (2)分解成的子问题是相同类型的子问题,具有最优子结构性质。

      (3)分解而成的更小的问题在解决之后可以合并出正确答案。

      (4)子问题是相互独立的,即子问题之间没有公共的子问题,当然也可以有,但是会降低效率,在出现众多重复子问题的时候常使用动态规划dp。

     

      1.3  使用步骤:

      (1)确定需要分解的问题大类。

      (2)分解成小问题后,解决小问题。

      (3)最后进行合并小问题,简称归并。

     

      1.4  常用工具:

      递归方法,递归,是指子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,是一种描述问题和解决问题的常用方法。递归有两个基本要素:
      ①边界条件,即确定递归到何时终止,也称为递归出口。
      ②递归模式,即大问题是如何分解为小问题的,也称为递归体。

     

      1.5  基本模板:

    T getAns(T l, T r,T i)
    {
            /* 结束条件 */
        if(l >= r)
            return r;
    
            /* 取得中值 */
        T mid = (l+r) >> 1;
    
            /* 二分递归 */
        if(满足的条件)      return getAns(l,mid,i+1);
        else              return getAns(mid,r,i+1);
    } 

    二、一道二分题点拨分治思想:

    2.1  题目来源:

    POJ:http://poj.org/problem?id=1064

    2.2  题目题干:

    Cable master

     2.3题目大意:

      每条电缆的长度都可以达到一厘米,并且告知必须切割的长度,可以精确地切割一厘米。
      通过编写一个程序确定可以从电缆上切下的电缆的最大可能长度,以获得指定的电缆数量。

     

    2.4题目思路:

      第一步:先书写满足要求的判断函数,即如下的(isGetNum)

      第二步:套用二分模板,修改部分内容。

      第三步:综合结果

     

    2.5题目AC代码:

    #include<stdio.h>
    #include<math.h>
    int n,m;
    double Ntemp[10005],maxx;
    bool isGetNum(double x)
    {
        int cnt = 0;
        for(int i = 0;i<n;i++)
            cnt += (int)(Ntemp[i] / x);
        return cnt >= m;
    }
    double getAns(double l, double r,int i)
    {
        if(fabs(l-r) < 1e-6)
            return r;
        if(i == 100) return r;
        double mid = (l+r) / 2;
        if(!isGetNum(mid))    return getAns(l,mid,i+1);
        else                return getAns(mid,r,i+1);
    }
    int main()
    {
        while(~scanf("%d %d",&n,&m))
        {
            maxx = 0;
            for(int i = 0;i<n;i++)
            {
                scanf("%lf",&Ntemp[i]);
                if(Ntemp[i] > maxx) maxx = Ntemp[i];
            }
            printf("%.2f
    ",floor(getAns(0,100001,1) * 100) / 100);
        }
        return 0;
     } 

    三、结对编程小结:

      刚开始很自信的就上来打题,过了样例就很自信的提交了,结果在一些测试点WA了,思前想后都觉得代码没有问题,结果是没有完整理清题意,在部分边界处理上出了点问题,还好最后也解决了出来,在后面的题中就很顺利就求解了。

      结对编程可以互相找出对方的不足之处,也可以齐心协力想出一个更好的算法,队友VS编码debug能力很强,编码过程愉快和谐,下次继续一起加油~。

  • 相关阅读:
    簡化SQL Insert、Update、Delete、Select的方法
    Microsoft SqlHelper Class
    EntLib5.0 日志应用程序块(logging) 使用与配置
    EnterpriseLibrary及Log4Net於WebConfig或AppConfig的相關配置
    LogHelper
    log4net使用详解
    Create\Move\Delte Folder\File
    Log4Net使用详解(续)
    DataSet 类(四)读写XML
    SqlDataAdapter类
  • 原文地址:https://www.cnblogs.com/WinniyGD/p/11664642.html
Copyright © 2020-2023  润新知