循环、递归、概率

递归是程序设计中的一种算法。一个过程或函数直接调用自己本身或通过其他的过程或函数调用语句间接地调用自己的过程或函数,称为递归过程或函数。

例子一:打靶

面试1:一个射击运动员打靶,靶一共有10环,连开10枪打中90环的可能性有多少种?

解析:靶上一共有10种可能——1环到10环,还有可能脱靶,那就是0环,加在一起公有11种可能。

方法1:使用循环

for(i1=0;i1<=10;i1++)
    for(i2=0;i2<=10;i2++)
        for(i3=0;i3<=10;i3++)
            ...
            for(i10=0;i10<=10;i10++)
            {
                if(i1+i2+i3+...+i10==90)
                print();
            }

但是,上面的循环程序虽然解决了问题,但时间复杂度和空间复杂度无疑是很高的,比较好的办法当然是采用递归的方式。

方法二:

递归的条件由以下4步完成:

1)如果出现这种情况,即使后面每枪都打10环也无法打够总环数90,这种情况下就不用再打了,则退出递归。代码如下:

if(score<0||score>(num+1)*10)   //次数num为0~9

{

  return;

}

2)如果满足条件且打到最后一次(因为必须打10次),代码如下:

if(num==0)

{

  output();

  return;

}

3)如果没有出现以上两种情况则执行递归,代码如下:

for(int i=0;i<=10;++i)

{

  //这里实际上为了方便把顺序倒了过来,store[num]是最后一次打的出现的环数

  //store[9]第10次打出现的环数,store[8]第9次打出现的环数,...,store[0]第一次打出现的环数

  store[num]=i;//每一次打都11种环数可以选择

  Cumput(score-i,num-1,store);

}

4)打印函数,符号要求的则把它打印出来,代码如下:

void output(int [] store)

{

  for(int i=9;i>=0;--i)

    cout<<store[i]<<" ";

  cout<<endl;

  sum++;

}

 完整代码:

#include<iostream>
#include<vector>
using namespace std;

long long global=0;
vector<vector<int> > res;
void Cumput(int score,int n,vector<int> &tmp)
{
    if(score<0||score>(n+1)*10)
        return;
    if(n==0)
    {
        global++;
        tmp.push_back(score);
        res.push_back(tmp);
        tmp.pop_back();
        return;
    }
    for(int i=0;i<11;i++)
    {
        tmp.push_back(i);
        Cumput(score-i,n-1,tmp);
        tmp.pop_back();
    }
}

int main()
{
    vector<int> tmp;
    Cumput(90,9,tmp);
    cout<<global<<endl;
    for(auto a:res)
    {
        for(auto v:a)
            cout<<v<<" ";
        cout<<endl;
    }
}

 

#include<iostream>
#include<vector>
using namespace std;

vector<vector<int> > res;
void Cumput(int score,int n,vector<int> &tmp)
{
    if(score<0||score>n*10)
        return;
    if(n==0&&score==0)
    {
        res.push_back(tmp);
        return;
    }
    for(int i=0;i<11;i++)
    {
        tmp.push_back(i);
        Cumput(score-i,n-1,tmp);
        tmp.pop_back();
    }
}

int main()
{
    vector<int> tmp;
    Cumput(90,10,tmp);
    cout<<res.size()<<endl;

}

 

例子二:

八皇后问题:

从每一行开始填充皇后检查是否满足要求,因此,如果是有效的皇后满足的条件是:

1)选择的列与前面已经防止皇后的列不在同一列。

2)检查从改行开始的第一行的主对角线是否满足要求

3)检查从该行开始到第一行的副对角线是否满足要求

#include<iostream>
#include<string>
#include<vector>
using namespace std;

class Solution
{
public:
    vector<vector<string> > solveNQueens(int n)
    {
        vector<string> str(n,string(n,'.'));
        vector<vector<string> > res;
        helper(str,n,0,res);
        return res;
    }
    void helper(vector<string> &str,int n,int start,vector<vector<string> > &res)
    {
        if(start==n)
        {
            res.push_back(str);
            return;
        }
        for(int col=0; col<n; col++)
        {
            if(isValid(str,start,col))
            {
                str[start][col]='Q';
                helper(str,n,start+1,res);
                str[start][col]='.';
            }
        }
    }
    bool isValid(vector<string> &str,int row,int col)
    {
        int i,j;
        for(i=0; i<row; i++)
        {
            if(str[i][col]=='Q')
                return false;
        }
        for(i=row-1,j=col-1; i>=0&&j>=0; i--,j--)
        {
            if(str[i][j]=='Q')
                return false;
        }
        for(i=row-1,j=col+1; i>=0&&j<(int)str.size(); i--,j++)
        {
            if(str[i][j]=='Q')
                return false;

        }
        return true;
    }
};

int main()
{
    Solution s;
    vector<vector<string> > result=s.solveNQueens(8);
    cout<<result.size()<<endl;
    for(auto a:result)
    {
        for(auto v:a)
            cout<<v<<endl;
        cout<<endl;
    }
}

 

例子三:求字符子集

见:http://www.cnblogs.com/wuchanming/p/4149941.html

 

例子四:0-1背包问题

#include<iostream>
#include<vector>
using namespace std;
void helper(vector<int> &num,int m,int n,int start,vector<vector<int> > &res)
{
    if(m==0)
    {
        res.push_back(num);
        return;
    }
    if(m<0)
        return;
    for(int i=start; i<=n; i++)
    {
        num.push_back(i);
        helper(num,m-i,n,i+1,res);
        num.pop_back();
    }
}
vector<vector<int> > calFun(int n,int m)
{
    vector<vector<int> > res;
    vector<int> num;
    helper(num,m,n,1,res);
    return res;
}

int main()
{
    vector<vector<int> > res=calFun(7,8);
    cout<<res.size()<<endl;
    for(auto a:res)
    {
        for(auto v:a)
            cout<<v<<" ";
        cout<<endl;
    }
}

 

时间: 2024-09-25 22:49:08

循环、递归、概率的相关文章

循环递归RNN,序列建模套路深(深度学习入门系列之十三)

系列文章一入侯门"深"似海,深度学习深几许(入门系列之一)人工"碳"索意犹尽,智能"硅"来未可知(深度学习入门系列之二)神经网络不胜语, M-P模型似可寻(深度学习入门系列之三)"机器学习"三重门,"中庸之道"趋若人(深度学习入门系列之四)Hello World感知机,懂你我心才安息(深度学习入门系列之五)损失函数减肥用,神经网络调权重(深度学习入门系列之六)山重水复疑无路,最快下降问梯度(深度学习入门系列

算法系列(十五) 循环和递归在算法中的应用

一.递归和循环的关系 1. 递归的定义 顺序执行.循环和跳转是冯·诺依曼计算机体 系中程序设计语言的三大基本控制结构,这三种控制结构构成了千姿百态的算法,程序,乃至整个软件世 界.递归也算是一种程序控制结构,但是普遍被认为不是基本控制结构,因为递归结构在一般情况下都可 以用精心设计的循环结构替换,因此可以说,递归就是一种特殊的循环结构.因为递归方法会直接或间接 调用自身算法,因此是一种比迭代循环更强大的循环结构. 2. 递归和循环实现的差异 循 环(迭代循环)结构通常用在线性问题的求解,比如多项

全面解读用于文本特征提取的神经网络技术:从神经概率语言模型到GloVe

作者:Vineet John 机器之心编译 参与:吴攀.李亚洲.蒋思源 文本特征提取是自然语言处理的核心问题之一,近日,加拿大滑铁卢大学的 Vineet John 在 arXiv 发布了一篇关于用于文本特征提取的神经网络技术的综述论文.机器之心对该论文进行了编译介绍,论文原文可点击文末「阅读原文」查阅. https://arxiv.org/abs/1704.08531 本论文的目标是促进有关使用神经网络架构的文本特征提取技术的讨论.本论文中所讨论的研究问题关注的是当前最佳的神经网络技术,它们已经

Mysql中的递归层次查询(父子查询)

最近遇到了一个问题,在mysql中如何完成节点下的所有节点或节点上的所有父节点的查询? 在Oracle中我们知道有一个Hierarchical Queries可以通过CONNECT BY来查询,但是,在MySQL中还没有对应的函数!!! 下面给出一个function来完成的方法 下面是sql脚本,想要运行的直接赋值粘贴进数据库即可. 创建表treenodes(可以根据需要进行更改) 12345678910 -- ---------------------------- -- Table stru

java 排列组合-求大神帮我看看这段代码,打印完“12345”结束for循环后为什么还能继续运行?新手没金币,抱歉!

问题描述 求大神帮我看看这段代码,打印完"12345"结束for循环后为什么还能继续运行?新手没金币,抱歉! public class Test { public static void main(String[] args) { prints(0 0 0 0 0);}public static void prints(int k1int k2int k3int k4int k5){ if(k5!=0){ System.out.println(k1*10000+k2*1000+k3*1

递归-java 打包压缩下载出错,求大神帮忙

问题描述 java 打包压缩下载出错,求大神帮忙 代码在这里 package cn.mobilizer.channel.image.vo; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.ut

oracle 使用递归的性能提示测试对比_oracle

当你用start with connect by nocycle prior 进行递归查找数据的时候那么下面两段代码的性能肯定是有明显差别的大家用的时候 请注意了代码可以不看下面 直接看我的总结 //查询某个文件夹文件夹ID=12里面的层次数以及 文件的个数 A:为文件之间的关联关系 上下级关系 B:为文件夹里面的文件 正解: 复制代码 代码如下: select count(0) cou,max(levels)+1 as levels select C.a1,C.a2,C.levels... f

添加根节点 循环数据-TreeView控件,把数据库的内容,循环绑定到一个写死的根节点上

问题描述 TreeView控件,把数据库的内容,循环绑定到一个写死的根节点上 我用的递归方法绑定数据,代码是这样的:private void BindDate(int Pid TreeNode PNode) { DataSet ds = cBll.GetList(""""); DataTable dt = ds.Tables[0]; if (dt.Rows.Count > 0) { DataView dv = new DataView(dt);//过滤Pare

php递归创建和删除文件夹的代码小结_php技巧

第一种方法: 复制代码 代码如下: <?php /** * 目录生成类 :UtilsMakeDir * @author yepeng * @since 2010.3.18 */ class UtilsMakeDir{ //基目录 建立目录时不会对这个目录进行建立.这应该是个已经存在的目录 private static $makeBasePath = 'video'; private static $delBasePath = 'video'; /** * 递归建立目录, * 建立成功返回这个全路

计算一个循环,小弟不懂,大侠们进来帮帮忙!

问题描述 6.有100个人围成一个圈(编号0-99),从第0号的人开始从1报数,凡报到3的倍数的人离开圈子,然后再数下去,直到最后只剩一个人为止,问此人原来的位置是多少号?(最好在有些重要的语句的时候附上点注释,谢啦!) 解决方案 解决方案二:小弟在线等!解决方案三:publicstaticvoidmain(String[]args){//初始化0-99个人List<Integer>personList=newLinkedList<Integer>();for(inti=0;i&l