算法设计备考笔记

第一章 算法概述

  1. 算法的定义:算法是解决问题的过程

  2. 算法的三要素:操作,控制结构,数据结构

  3. 算法的五大基本特征:

    • 有穷性
    • 确定性
    • 可行性
    • 零个或多个输入
    • 一个或多个输出
  4. 算法的复杂性:时间复杂度&空间复杂度

  5. 时间复杂度的衡量方法:事前分析估算法,事后分析法

  6. 常数级-阶乘级,至顶向下复杂度越来越大


    IMG_20211221_234601.jpg
  7. 大O表示法中的大O是复杂度的上界

第二章 迭代与蛮力

  1. 迭代法的定义:是一种用旧值推出新值的算法

  2. 迭代法的实现步骤:

    1. 确定迭代模型
    2. 确定迭代关系式
    3. 对迭代过程进行控制
  3. 迭代法有两种:

    • 正推法(递推法)
    • 倒推法
  4. 正推法的示例:兔子繁殖

  5. 倒推法:猴子吃桃

  6. 蛮力法定义:枚举法(穷举法)是蛮力法的一种表现形式,它是根据问题中的条件将可能的情况一一列举出来,逐步尝试求解

  7. 蛮力法的步骤:

    1. 找出枚举范围
    2. 找出约束条件
  8. 蛮力法的应用:百钱百鸡

  9. 百钱百鸡算法:

    for(int x = 1; x <= 20; x++){ // 公鸡
        for(int y = 1; y<= 33; y++){ // 母鸡
            int z = 100 - x - y; // 小鸡
            if((z % 3 == 0) && (x * 5 + y * 3 + z / 3 == 100))  //核心
        }
    }
    

第三章 分治法

  1. 分治法是用递归实现的

  2. 分治法的定义:将一个难以直接解决的大问题分割为几个规模较小的相似问题,再逐个击破

  3. 分治法的步骤:

    1. 分解
    2. 解决
    3. 合并
  4. 适用于分治法的问题所应具备的特征:

    1. 问题能够被分解,且分解后最好相互独立
    2. 每个小问题都是相似的
    3. 合并之后能够推出原问题的解
  5. 分治法的应用:金砖问题

  6. 金砖问题算法:

    float a[n];
    maxmin(int i, int j, float & fmax, float & fmin){
        int mid; 
        float lmax, lmin, rmax, rmin;
        if (i=j){
            fmax=a[i];
            fmin=a[i];
        }else if (i=j-1){
            if(a[i] < a[j]){
                fmax = a[j];
                fmin = a[i];
            }else{
                fmax = a[i];
                fmin = a[j];
            }
        }else{
            mid = (i+j)/2;       //核心
            maxmin(i, mid ,lmax,lmin);
            maxmin(i, mid, lmax, lmin);      //核心
            if(lmax>rmax)
                fmax = lmax;
            else
                fmax = rmax;
            if(lmin>rmin)
                fmin = rmin;
            else
                fmin = lmin;
        }
     
        
    }
    
  7. 最大子段和问题是用分治法解决的

第四章 贪心算法

  1. 贪心算法又叫贪婪算法,登山算法
  2. 贪心算法的根本思想以逐步的局部最优,达到最终的全局最优
  3. 选择贪心算法需要具有无后向性
  4. 贪心算法的应用:付款问题,币种统计问题,取数游戏问题
  5. 贪心算法的基本思想:从问题的某一个初始解出发,逐步逼近给定的目标,每一步都做一个不可回溯的决策,尽可能的求出最好的解,当达到某算法中的某一步,不需要再前进时,算法停止

第五章 动态规划

  1. 动态规划的基本思想(动态规划和分治法的异同点):动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解,与分治法不同的是,适合用于动态规划求解的问题,经分解得到的子问题,往往不是互相独立的,若用分治法来解决这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次

  2. 最长公共子序列问题是使用动态规划来解决的

  3. 最大子段和不仅可以用动态规划来解决,也可以用分治法解决

  4. 仅需知道对于p(i,j)或者p(k,w)都是指i的最优值

2.png
  1. 递推关系式的推导方法:(掌握如何推导)
1.png
  1. 求解最优值

    int w[4] = {2,3,4,5};
    int v[4] = {3,4,5,6};
    for(int i=1; i<=n; i++){
        for(int j=1;j<=c,j++){
            if(w[i-1]>j){        //核心代码
                p[i][j] = p[i-1][j];
            }else{
                p[i][j] = max(p[i-1][j-w[i-1]]+v[i-1],p[i-1][j]);
            }
        }
    }
    
  2. 求解最优解

    int isp[n];
    j = c;
    for (i = n; i > 0; i--){
        if(p[i][j]>p[i-1][j]){       //核心代码
            isp[i] = 1;
            j = j - w[i-1];
        }else{
            isp[i] = 0;
        }
    }
    
  1. 矩阵链式方程-状态转移方程

    m(i,j)代表最小相乘次数,熟记状态转移方程

image-20211222013118943-16401078819418.png

第六章 图的搜索

  1. 图的定义:顶点的集合以及边的集合,顶点不能为空,边不能为空

  2. 图的搜索办法:

    • 广度优先
    • 深度优先
  3. 深度优先搜索的主要思想:

    首先以一个未被访问过的顶点作为起始顶点,延当前顶点的边走到为访问过的顶点,当没有未访问的顶点时,则回到上一个顶点,继续试探访问别的顶点,直到所有的顶点都被访问

  4. 广度优先搜索的主要思想

    从根节点开始,沿着树的宽度遍历树的结点

第七章 回溯法

  1. 回溯的基本做法是搜索(深度优先)

  2. 回溯法的步骤:从根节点出发搜索解空间树

  3. 回溯法的基本思想:

    回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树,算法搜索至解空间树的任意结点时,先判断该结点是否包含问题的解,如果肯定不包含,则跳过以该结点为根的子树的搜索,逐层向其祖先节点回溯,否则进入该子树,继续按深度优先策略搜索,回溯法计算问题的所有解时,要回溯到根,且根结点的所有子树都已经被搜索完成才结束

  4. 需要强调的是,问题的解空间树是虚拟的,并不需要在算法运行时构造一棵真正的树结构

  5. 回溯法属于蛮力穷举法,时间复杂度不会太好或者太差,在最坏情况下,时间代价肯定为指数阶

  6. 在n皇后问题的可能解中,对应的解空间树有n!个叶子结点,每个叶子结点代表一种可能解,在n=4的情况下,解空间树有65个结点,24个叶子结点

  7. 虽然解空间树共有65个结点,24个叶子结点,但在实际搜索过程中,遍历操作只涉及27个结点就找到了满足条件的解,原因在于剪枝函数

  8. 图的着色问题是使用回溯法解决的

  9. 旅行商问题是使用回溯法解决的

  10. 教材P218-P219页4,5,6,7,8会考察,尤其关注4,5

    1. 第四题:n皇后问题:

      #include <stdio.h>
      const int N=10; 
      int a[N]; 
      int count,n;   
       
       
      bool check(int x,int y){  
       for(int i=1;i<=x;i++){
           if(a[i]==y) return false;   
           if(i+a[i]==x+y) return false;  
           if(i-a[i]==x-y) return false;  
       } 
       return true; 
      }
      Print(int n){
       count++;   
       printf("第%d种解",count);
       for(int i=1;i<=n;i++){
           printf("(%d,%d)",i,a[i]);
       } 
       printf("\n");
      }
       
      
      void dfs(int row){
       if(row>n) {  
           Print(n); 
           return ;
       }
       for(int i=1;i<=n;i++){
           if (check(row,i)){  
               a[row]=i; 
               dfs(row+1);  
               a[row]=0; 
           }
       }
      } 
      int main(){
       printf("输入n*n的棋盘数:"); 
       scanf("%d",&n);
       dfs(1);  
       printf("一共有%d种解",count);
       return 0; 
      }
      
    2. 第五题:求子集问题:

      #include<iostream>
      using namespace std;
       
      #define NUM 10000
      int n;
      int c;
      int cw;
      int bestw;
      int w[NUM];
      int x[NUM];
      int r;
      bool flag;
       
      void backtrack(int t)
      {
       if(t>n)
       {
           if(cw==c)
           {
               for(int i=1; i<=n; i++)
                   if (x[i]) printf("%d ",w[i]);
               printf("\n");
               flag = false;
           }
           return;
       }
       r -= w[t];
       if (cw+w[t]<=c)
       {
           x[t] = 1;
           cw += w[t];
           backtrack(t+1);
           cw -= w[t];
       }
       if (cw+r>bestw)
       {
           x[t] = 0;
           backtrack(t+1);
       }
       r += w[t];
      }
       
      int main()
      {
       while(scanf("%d%d",&n,&c) && (n||c))
       {
           r = 0;
           for(int i=1; i<=n; i++)
           {
               scanf("%d", &w[i]);
               r += w[i];
           }
           cw = 0;
           bestw = 0;
           flag = true;
           backtrack(1);
           if (flag) printf("No Solution!\n");
       }
       return 0;
      }
      

痛斥一切认为理所应当的坐享其成者!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容