算法处探:递归练习

  • 求两个串的最大公共子序列

    此题要注意子序列和子串的概念。

    假如两个串第一个位置的元素相同,那么只需比较两串剩余的部分的公共子序列长度。

    如果不同,有两种情况:

    ​ 1.比较字串A剔除第一个位置元素与字串B的公共子序列

    ​ 2.比较字串A和字串B剔除第一个位置元素的公共子序列

    取两种情况的最大值。

#include <bits/stdc++.h>
using namespace std;
//求两个串的最大公共子序列
int f(string s1, string s2)
{
    if(s1.size() == 0 || s2.size() == 0)
        return 0;
    if(s1[0] == s2[0])
        return f(s1.substr(1,s1.size()), s2.substr(1,s2.size())) + 1;//剩余部分
    else
        return max(f(s1.substr(1, s1.size()), s2), f(s1, s2.substr(1, s2.size())));
}
int main()
{
    string s1;
    string s2;
    cin>>s1>>s2;
    int k = f(s1, s2);
    cout<<k;
    return 0;
}
  • 在n个球中,任意去取m个(不放回), 求有多少种不同取法

    假设有一个特殊球,此球的状态只有两种:被取到和没有被取到。

    若被取到,那么只需在n-1个球中取m-1个球。

    若没有被取到,需在n-1个球中取m个球。

    #include <bits/stdc++.h>
    using namespace std;
    //在n个球中,任意去除m个(不放回), 求有多少种不同取法
    int f(int n, int m)
    {
        if(n<m)
            return 0;
        if(n==m)
            return 1;
        if(m==0)
            return 1;
    
        return f(n-1,m-1) + f(n-1, m);  // 找一个特殊球
    }
    int main()
    {
        int n, m;
        cin>>n>>m;
        int k = f(n, m);
        cout<<k;
        return 0;
    }
    
    
  • 求n个元素的全排列

    第一个位置n个元素都有可能,所以将第一个位置的元素与后面的每个元素进行交换。

    每交换一次,第一个位置的元素就确定了,然后将剩余的部分也进行全排列,进行同样操作。

    但是注意最后要再交换回来。

    #include <bits/stdc++.h>
    using namespace std;
    //求n个元素的全排列
    void f(string s, int k)
    {
        if(k==s.size())
        {
            cout<<s<<endl;
        }
       for(int i=k;i<s.size();i++)
       {
           char ch = s[k]; s[k] = s[i]; s[i] = ch; // 试探
           f(s, k+1);
           ch = s[k]; s[k] = s[i]; s[i] = ch; // 回溯
       }
    }
    int main()
    {
        string s;
      cin>>s;
        f(s, 0);
        return 0;
    }
    
    
  • 求反转串

    #include <bits/stdc++.h>
    using namespace std;
    //求反转串:如,cba->abc
    string f(string s)
    {
        if(s.length() < 2)
            return s;
        return f(s.substr(1,s.size())) + s[0];
    }
    int main()
    {
        string s;
        cin>>s;
        cout<<f(s);
        return 0;
    }
    
  • 计算杨辉三角第n层的第m个系数

    第m层第n的系数的值等于 第n-1层第m个系数+第n-1层第m-1个系数。

    如果n=0或者m=1,返回1.

    #include <bits/stdc++.h>
    using namespace std;
    //计算杨辉三角第n层的第m个系数,m和n都从0开始
    int f(int n, int m)
    {
        if(m==0)
            return 1;
        if(m==n)
            return 1;
        return f(n-1, m) + f(n-1, m-1);
    }
    int main()
    {
        int n,m;
        cin>>n>>m;
        cout<<f(n, m)<<endl;
        return 0;
    }
    
  • 计算m个A,n个B可以有多少个不同排列

    从第一个位置开始,可能选A,也可能选B。

    如果选A,那么以后的位置需要排列m-1个A和n个B。

    如果选B,以后的位置需要排列n个A和n-1个B。

    #include <bits/stdc++.h>
    using namespace std;
    //计算m个A,n个B可以有多少个不同排列
    int f(int m, int n)
    {
        if(n==0 || m==0)
            return 1;
        return f(m-1, n) + f(m, n-1); 
    }
    int main()
    {
        int m, n;
        cin>>m>>n;
        cout<<f(m, n)<<endl;
        return 0;
    }
    
  • 整数分划问题

    数组a用来保存分划的数

    k是当前的位置

    #include <bits/stdc++.h>
    using namespace std;
    //整数的分划问题
    void f(int n, int a[], int k)
    {
        if(n==0)
        {
            for(int i=0; i<k; i++)
                cout<<a[i]<<" ";
            cout<<endl;
            return ;
        }
    
        for(int i=n; i>0; i--)
        {
            if(k>0 && a[k-1]<i)
                continue;
            a[k] = i;
            f(n-i, a, k+1);
        }
    }
    int main()
    {
        int n;
        cin>>n;
        int a[100];
        f(n, a, 0);
        return 0;
    }
    
    
  • 查账单

    err_sum:错误总金额

    cur_sum:前面元素的累加和

    k:当前要处理的元素位置

    b:对应a中元素是否是漏掉的

    #include <bits/stdc++.h>
    using namespace std;
    //查账单
    //输入第一行是有错的总金额
    //接下来是n,表示将要输入的明细账目的条数
    //再接下来是n行整数,分别表示每笔账目的数目
    //要求输出可能漏掉的金额组合
    
    int n; //账目条数
    void f(int err_sum, int *a, int k, int cur_sum, bool *b)
    {
        if(cur_sum > err_sum)
            return ;
        if(cur_sum == err_sum)
        {
            for(int i=0; i<n; i++)
                if(!b[i])
                    cout<<a[i]<<" ";
            cout<<endl;
            return ;
        }
        if(k >= n)
            return ;
    
        b[k] = false;
        f(err_sum, a, k+1, cur_sum, b); // 不加到错误账单中
    
        b[k] = true;
        cur_sum += a[k];
        f(err_sum, a, k+1, cur_sum, b); // 加到错误账单中
    
        b[k] = false; // 回溯
    }
    int main()
    {
    
        int err_sum;//保存有错的总金额
        int *a;//n条账目明细
        bool *b;
        cin>>err_sum>>n;
        a = new int[n];
        b = new bool[n];
        for(int i=0; i<n; i++)
            cin>>a[i];
        f(err_sum, a, 0, 0, b);
        return 0;
    }
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容