算法设计复习(一二递推递归)

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法设计复习(一二递推递归)相关的知识,希望对你有一定的参考价值。

第一章 算法概述

什么是算法:是对特定问题求解步骤的一种描述,是指令的有限序列。
算法的五个重要特性:输入、输出、有穷性、确定性、可行性
一个算法的优劣可以用时间复杂性和空间复杂性来衡量
算法和程序的关系
1.程序是使用某种程序设计语言对算法的具体实现,是对算法的精确描述,可在计算机上运行;
2.程序可以是无穷的,而算法必须是有穷的;
3.程序设计的核心是算法。
常用的描述算法的方法:自然语言、流程图、程序设计语言、伪代码等
排序算法:
直接插入排序:


第二章 STL简介

掌握有关vector的内容
vector(向量)从后面快速插入与删除,直接访问任何元素

vector和数组的区别
1.array 定义的时候必须定义数组的元素个数;而vector 不需要
2.array 定义后的空间是固定的了,不能改变;而vector 要灵活得多,可再加或减
3.vector有一系列的函数操作,非常方便使用
4.数组和vector不同,一个数组不能用另一个数组初始化,也不能将一个数组赋值给另一个数组;

知道set具有典型的特点: 内部的元素依据其值自动排序;set内的相同数值的元素只能出现一次

#include <bits/stdc++.h>

using namespace std;
int n;
map<string,int>mp;

int main()

    while(cin>>n)
    
        string tmp;
        int g=0;
        for(int i=1;i<=n;i++)
        
            string k;
            cin>>k;
            mp[k]++;
            if(mp[k]>g)
                tmp=k,g=mp[k];
        
        cout<<"answer:"<<tmp<<endl;
    
    return 0;


了解有关“优先队列”的内容,关键是会使用优先队列去解决问题(默认情况下是使用大顶堆,是从大到小排列)

#include <bits/stdc++.h>

using namespace std;
struct cmp

    bool operator()(int x,int y)
    
        return x<y;
    
;
//priority_queue<int,vector<int>,greater<int>>q;
priority_queue<int,vector<int>,cmp>q;

int main()

    int n;cin>>n;
    for(int i=1;i<=n;i++)
    
        int x;cin>>x;
        q.push(x);
    
    while(!q.empty())
    
        cout<<q.top()<<endl;q.pop();
    
    return 0;


STL其它内容不做要求


递推方法解决:
菲波那契数列:f[i]=f[i-2]+f[i-1]
汉诺塔移动次数:f(n)=2*f(n-1)+1
猴子吃桃:f[i]=2*f[i+1]+2
骨牌铺满方格

f(n)=f(n-1)+f(n-2)   (n>2f(1)=1 
f(2)=2 

蜜蜂路线:f[i]=f[i-1]+f[i-2]
吃糖果:f[i] = f[i - 1] + f[i - 2]

昆虫繁殖:

b[i] = f[ i - x] * y; (成虫经过x月产卵 y个)
f[i] = f[ i - 1] + b[ i - 2]; (卵经过2个月长成成虫)

第3章 递归与分治策略

分治是一种算法思想,递归是实现这种思想的一种手段

n!

int fun(int n)

   if(n==1)
       return 1;
   return n*fun(n-1);

菲波那契数列

#include <bits/stdc++.h>

using namespace std;
int n;
int fibo(int x)

    if(x==1||x==2)
        return 1;
    return fibo(x-1)+fibo(x-2);

int main()

    while(cin>>n)
    
        cout<<"fibo["<<n<<"]="<<fibo(n)<<endl;
    
    return 0;

猴子摘桃问题

#include <bits/stdc++.h>

using namespace std;
int n;
int fun(int x)

    if(x==10)
        return 1;
    return 2*fun(x+1)+2;

int main()

    cout<<"请输入想知道的第几天的桃子数目: ";
    while(cin>>n)
    
        cout<<"answer: "<<fun(n)<<endl;
    
    return 0;

十进制转换为二进制

string s;
void fun(int n)

    if(n==0)
        return;
    fun(n/2);
    s+=n%2+'0';

int main()

    cin>>n;
    fun(n);
    cout<<s<<endl;
    return 0;

逆序(或正序)输出一个正数中的每一位数

void fun(int n)

    if(n==0)
        return;
    s+=n%10+'0'; //逆序
    fun(n/10);
    //s+=n%10+'0'; //正序

集合的全排列

#include <bits/stdc++.h>

using namespace std;
const int N=1e5+5;
int n,a[N],k=0;
void perm(int x)

    if(x==n+1)
    
        k++;
        for(int i=1;i<=n;i++) cout<<a[i]<<" ";
        cout<<endl;
        return;
    
    for(int i=x;i<=n;i++)
    
        swap(a[x],a[i]);
        perm(x+1);
        swap(a[x],a[i]);
    

int main()

    cin>>n;
    for(int i=1;i<=n;i++) a[i]=i;
    perm(1);
    cout<<k<<endl;
    return 0;

递归求平方和函数(openjudge题目)

#include <bits/stdc++.h>

using namespace std;
const int N=1e5+5;
int n,a[N],k=0,ans;
int fun(int n)

   if(n==1)
       return 1;
   return n*n+fun(n-1);

int main()

    cin>>n;
    cout<<fun(n)<<endl;
    return 0;

棋盘覆盖

#include <bits/stdc++.h>

using namespace std;
const int N=1e3+5;
int tp,board[N][N];
void CB(int tr,int tc,int dr,int dc,int sz)

    if(sz==1) return;
    int t=++tp,s=sz/2;
    //处理左上角
    if(dr<tr+s&&dc<tc+s)
        CB(tr,tc,dr,dc,s);
    else
    
        board[tr+s-1][tc+s-1]=t;
        CB(tr,tc,tr+s-1,tc+s-1,s);
    
    //处理右上角
    if (dr < tr + s && dc >= tc + s) // 特殊方格在此棋盘中
        CB(tr, tc+s, dr, dc, s);
    else
    
        board[tr + s - 1][tc + s] = t;
        CB(tr,tc+s,tr+s-1,tc+s, s);
    
    //处理左下角
    if (dr >= tr + s && dc < tc + s) // 特殊方格在此棋盘中
        CB(tr+s, tc, dr, dc, s);
    else
    
        board[tr + s ][tc + s-1] = t;
        CB(tr+s,tc,tr+s,tc+s-1, s);
    
    //处理右下角
    if (dr >= tr + s && dc >= tc + s) // 特殊方格在此棋盘中
        CB(tr+s, tc+s, dr, dc, s);
    else
    
        board[tr + s ][tc + s] = t;
        CB(tr+s,tc+s,tr+s,tc+s, s);
    

int main()

    CB(0,0,1,3,4);
    for(int i=0;i<4;i++)
    
        for(int j=0;j<4;j++)
            cout<<board[i][j]<<" ";
        cout<<endl;
    
    return 0;


找出这n个元素中第k小的元素(掌握线性时间选择法解决此问题)

#include <bits/stdc++.h>

using namespace std;
const int N=1e3+5;
int n,a[N];
int select(int l,int r,int k)

    if(l>=r) return a[l];
    int pivot=a[l],i=l,j=r+1;
    while(1)
    
        doi=i+1;while(a[i]<a[pivot]);
        doj=j-1;while(a[j]>a[pivot]);
        if(i>=j) break;
        swap(a[i],a[j]);
    
    if(j-l+1==k)
        return pivot;
    a[l]=a[j];
    a[j]=pivot;
    if(j-l+1>k)
        return select(l,j-1,k); //左半区找
    else
        return select(j+1,r,k-j+l-1); //右半区找


int main()

    cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    cout<<select(0,n-1,2)<<endl;
    return 0;

半数集问题

int comp(int x)

    int ans=1;
    for(int i=1;i<=x/2;i++)
        ans+=comp(i);
    return ans;

int comp(int x)

    if(a[x]) return a[x];
    int ans=1;
    for(int i=1;i<=x/2;i++)
        ans+=comp(i);
    a[x]=ans;
    return ans;

整数因子分解问题

#include <bits/stdc++.h>

using namespace std;
const int N=1e3+5;
int n,ans;
void fun(int x)

    if(x==1)
    
        ans++;return;
    
    for(int i=2;i<=x;i++)
        if(x%i==0)
            fun(x/i);

int main()

    cin>>n;
    fun(n);
    cout<<ans<<endl;
    return 0;


汉诺塔移动次数:移动次数为(2^n-1)

#include <bits/stdc++.h>

using namespace std;
int x;
void move(char from ,char to)

    x++;
    cout<<"Move "<<from<<","<<to<<endl;

void hanoi(int n, char first, char second,  char third)

    if(n==1)
    
        move(first,third);
        return;
    
    hanoi(n-1,first,third,second);  //n-1个盘子通过第三个托到第二个托上
    move(first,third);
    hanoi(n-1,second,first,third);

 

int main()

    int m;
    cout<<"the number of diskes:";
    cin>>m;
    cout<<"move  "<<m<<" diskes:\\n";
    hanoi(m,'A','B','C');
    cout<<"result: "<<x<<endl;
    return 0;

n个数的划分:

#include <bits/stdc++.h>

using namespace std;
const int N=1e5+5;
int n,a[N],k=0;
void perm(int x)

    if(x==n+1)
    
        k++;
        for(int i=1;i<=n;i++) cout<<a[i]<<" ";
        cout<<endl;
        return;
    
    for(int i=x;i<=n;i++)
    
        swap(a[x以上是关于算法设计复习(一二递推递归)的主要内容,如果未能解决你的问题,请参考以下文章

《数据结构与算法之美》22——递归树

JavaScript 数据结构与算法之美 - 归并排序快速排序希尔排序堆排序

算法分析| 系列4(解决递推)

算法分析基础——递归树求解递推方程

计算机算法 期末复习个人笔记(部分)

《数据结构与算法之美》09——排序归并排序与快速排序