回溯算法求关于排列有关问题

八皇后问题就是一个典型的全排列问题了,这个在有一篇博客已经写过了,但是今天想在这里对于排列问题来一个总结。

排列问题主要涉及到以下几个方面:

1.不带重复数的全排列

2.带重复数的全排列

3.有限个数的全排列(例如从n个数里面选择m个数,m<n)

现在就以上几个方面把代码给大家,能理解则理解,不能理解就背下来,这种解法效率还是挺高的。

代码前提:所有的数据我都默认从0到n-1,如果在实际运用中,有可能需要进行变化。

1.不带重复数的全排列

#include<iostream>
using namespace std;
int t=0;//代表最后我算出来的结果数
int c[100];//例c[0]=2,在第0行中第一个元素在第2列(用下标莫见怪)
bool isok(int row)
{
    for(int x=0;x!=row;x++){//row代表所选的数不在同一行就可以;
        if(c[x]==c[row]){//如果他们在同一列就终止
            return false;
        }
    }
    return true;
}
void queen(int n,int row)
{
    if(row==n){
        t++;
        for(int i=0;i<n;i++){
            cout << c[i] << ‘ ‘;
        }
        cout << endl;
        return ;
    }
    else{
        for(int x=0;x!=n;x++){
            c[row]=x;
            if(isok(row)){
                queen(n,row+1);
            }
        }
    }
}
int main()
{
    int n;
    cin >> n;
    queen(n,0);
    cout << t;
    return 0;
}

2.带重复数的全排列

#include<iostream>
using namespace std;
int t=0;//代表最后我算出来的结果数
int c[100];//例c[0]=2,在第0行中第一个元素在第2列(用下标莫见怪)
void queen(int n,int row)
{
    if(row==n){
        t++;
        for(int i=0;i<n;i++){
            cout << c[i] << ‘ ‘;
        }
        cout << endl;
        return ;
    }
    else{
        for(int x=0;x!=n;x++){
            c[row]=x;
            queen(n,row+1);
        }
    }
}
int main()
{
    int n;
    cin >> n;
    queen(n,0);
    cout << t;
    return 0;
}

带重复数的全排列,也就是说,我不需要考虑这一列是否有元素已经放入了,我想放就放

3.有限个数的全排列(例如从n个数里面选择m个数,m<n)

#include<iostream>
using namespace std;
int t=0;
int c[100];
bool isok(int row)
{
    for(int x=0;x!=row;x++){//row代表所选的数不在同一行就可以;
        if(c[x]==c[row]){//如果他们在同一列就终止
            return false;
        }
    }
    return true;
}
void queen(int n,int m,int row)
{
    if(row==m){
        t++;
        for(int i=0;i<m;i++){
            cout << c[i] << ‘ ‘;
        }
        cout << endl;
        return ;
    }
    else{
        for(int x=0;x!=n;x++){
            c[row]=x;
            if(isok(row)){
                queen(n,m,row+1);
            }
        }
    }
}
int main()
{
    int n,m;//从n个数选择m个数
    cin >> n >> m;
    queen(n,m,0);
    cout << t;
    return 0;
}

原文地址:https://www.cnblogs.com/sddr/p/10752213.html

时间: 2024-11-01 10:54:57

回溯算法求关于排列有关问题的相关文章

回溯算法求素数环

原文地址:http://www.cnblogs.com/xwz0528/p/4638242.html 一. 问题描述 把从1到n(n>=2)这n个数摆成一个环,要求相邻的两个数的和是一个素数,找出所有满足条件的环. 二. 问题分析 1> 解向量:<x1, x2, ··· , xn> 2> 解空间树:排列树,(n-1)!个叶子结点 3> 剪枝函数:isPrime( x[t-1]+x[t] ),t=2,3,···,n  约束函数 三. 算法实现 1 #include<

排列组合和回溯算法-面试题

排列组合 排列组合通常用于在字符串或序列的排列和组合中,其特点是固定的解法和统一的代码风格.通常有两种方法:第一种是类似动态规划的分期摊还的方式,即保存中间结果,依次附上新元素,产生新的中间结果:第二种是递归法,通常是在递归函数里,使用for循环,遍历所有排列或组合的可能,然后在for循环语句内调用递归函数. 回溯 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法.回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来 ,换一条路再试.用回溯算法解决问题的一般步骤为: 1.定义一个解

LeetCode46 回溯算法求全排列,这次是真全排列

本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode的26篇文章,我们来实战一下全排列问题. 在之前的文章当中,我们讲过八皇后.回溯法,也提到了全排列,但是毕竟没有真正写过.今天的LeetCode46题正是让我们生成给定元素的全排列. 题意很简单,只有一句话,给定一个没有重复元素的序列,让我们返回这个序列所有的全排列,并且我们不需要考虑这些排列的顺序. 回溯法 我们在之前的文章当中分析过,全排列问题,可以看成是搜索问题,从而近似成八皇后问题.在八皇后问题当中,我们枚

c2java 回溯,下一个排列和子集和

穷举:生成所有候选解,然后找出需要的解. 回溯:把解表示成向量,每个分量取自一个有限集合.从部分解开始,每次添加解的一个分量,然后判断如果有可能扩展成完整解则递归下去,否则换成下一个.可以看做是隐式图上的深度优先搜索. 回溯/穷举的复杂度,最坏时和后者一样,通常情形因为不必遍历所有子节点,还是比较快的. 回溯框架: backtrack(a[], k) if a[0,...,k] is a solution output; else k = k + 1; for c: the i-th of ca

从零开始学回溯算法

本文在写作过程中参考了大量资料,不能一一列举,还请见谅. 回溯算法的定义:回溯算法也叫试探法,它是一种系统地搜索问题的解的方法.回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试. 解题的一般步骤是: 1.定义一个解空间,它包含问题的解: 2.利用适于搜索的方法组织解空间: 3.利用深度优先法搜索解空间: 4.利用限界函数避免移动到不可能产生解的子空间. 问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性. 话不多说,我们来看几个具体的例子慢

回溯算法-C#语言解决八皇后问题的写法与优化

结合问题说方案,首先先说问题: 八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 嗯,这个问题已经被使用各种语言解答一万遍了,大多还是回溯法解决的. 关于回溯算法:个人理解为就是优化的穷举算法,穷举算法是指列出所有的可能情况,而回溯算法则是试探发现问题"剪枝"回退到上个节点,换一条路,能够大大提高求解效率. 具体到8皇后问题上来说,需要考虑以下几点: 1)将8个皇后定义为8行中的相对位置来标识,考虑增

回溯算法入门及经典案例剖析(初学者必备宝典)

前言 基于有需必写的原则,并且当前这个目录下的文章数量为0(都是因为我懒QAQ),作为开局第一篇文章,为初学者的入门文章,自然要把该说明的东西说明清楚,于是...我整理了如下这篇文章,作者水平有限,有不足之处还望大家多多指出~~~ 概念 首先,回溯是什么意思?很多初学者都会问这样的一个问题.我们可以举这样一个例子: 1 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 我们看到了如图所示的一个4*4的迷宫了,我们假设数字1标记的位置为道路,数字0标记的位置为一堵墙,一个人由起点(0.0

递归、回溯-算法框架

之前已经学习过回溯法的一些问题,从这篇文章开始,继续深入学习一下回溯法以及其他经典问题. 回溯法有通用的解题法之称.用它可以系统的搜索一个问题的所有解或任一解,回溯法是一个既带有系统性又带有跳跃性的搜索算法. 它的问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树.算法搜索至解空间树的任一结点时,先判断该结点是否包含问题的解.如果肯定不包含,则跳过对以该结点为根的子树的搜索,逐层向其祖先结点回溯.否则,进入该子树,继续按深度优先策略搜索.回溯法求问题的所有解时,要回溯到根,且根结点的所有

回溯算法之素数环

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SeqListSort { /// <summary> /// <ather> /// lihonglin /// </ather> /// <content> /// 把从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数. ///分析:用回溯算法,考察所有