例题1.4 排列问题

题目

已知集合R={r1,r2,…,rn},请设计一个算法生成集合R中n个元素的全排列。

思路

令Rj=R-{rj}

记集合X中元素的全排列记为perm(X)。那么(rj)perm(X)表示在全排列perm(X)的每一种排列前加上前缀rj所得到的全排列。所以,R的全排列可归纳为

perm(R)={

  r1      当n=1

  (r1)perm(R1)+(r2)perm(R2)+…+(rn)perm(Rn)   当n>1

}

function swap(a,i,j){
    var temp=a[i]
    a[i]=a[j]
    a[j]=temp
}
var mk=1
function perm(a,k,m,pk,pm){

    if(k==m){
        console.log(mk++,a)
    }else{
        for(var i=k;i<=m;i++){
            swap(a,k,i)
            perm(a,k+1,m,pk,pm)
            swap(a,k,i)
        }
    }
}
perm(["a","b","c","d"],0,3);有24中排列方式

  

时间: 2024-08-03 14:53:55

例题1.4 排列问题的相关文章

【第二章例题2-4】排列问题

输入n个数字,输出它的所有排列 [题解] 总体的思路就是先产生一个数字的排列 ①->从后面n-1个数字中挑一个数字到第一个位置上替换它(n-1)个方案. ②生成后面n-1数字的排列. 一直重复这个两个步骤就可以了 (感觉是比之前那种flag[]数组法好用的方法) [代码] #include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int N = 10;

关于next_permutation 例题:[P4163 [SCOI2007]排列

ouyang语重心长:一定要把这个函数名记到哦!来,我们一起念一道:next_permunation 看来我英语还是太撇了-- STL提供了两个用来计算排列组合关系的算法,分别是next_permutation和prev_permutation. 算法思想: 1.首先从最尾端开始往前寻找两个相邻元素,令第一元素为i,第二元素为ii,且满足i<ii. 2.找到这样一组相邻元素后,再从最尾端开始往前检验,找出第一个大于i的元素,令为j,将i,j元素对调(swap). 3.再将ii之后的所有元素颠倒(

状态压缩与二进制

自己最烦二进制,但还是痛定思痛,耐心学着... 普通的数都是十进制,二进制便是逢2进一,我觉得它最大的用途就可以表示一系列的东西用于不用上,用则为1,不用为0,比如说四个物体,可以用1111表示,再把1111用十进制表示15,这样15就可以表示这一状态. 说从最基础的说起:一般的n个物体,用二进制表示就需要有n个位置,这时的十进制是多少呢?可以用<<表示,例如1<<2,就表示100,那n个物体就需要1<<n,才能表示1后n个0,前面要多一个1,因为你要把n个1的情况也包

浅谈康托展开和其逆运算

康托展开,是一种在\(\mathcal{O}(n^2)\)(\(n\)为排列元素个数)时间复杂度求解某一排列在全排列中的次序的算法. 我们以一道例题引入: 排列的序号 题目描述: 给定一个数\(n\)和一个\(n\)个数的排列\(a\),求\(a\)在\(n\)的全排列中的序号. 输入描述: 第一行一个整数\(n\),第二行一个排列\(a\). 输出描述: 求\(a\)在\(n\)的全排列中的序号. 输入输出样例: 输入 3 123 输出 1 数据范围 \(n\le 15\) 根据排列组合.加法

错位排列及有关例题

求n个数(不相同)错位排列的个数. 何为错位排列?定义如下:对于n的一个排列a1,a2,a3...an. 如何求解错位排列? 考虑动态规划的解法. 前i个元素时如何进行状态转移? (一)首先由于要求错位排列,第i个元素肯定不会放在自己的位置上,故第i个元素的位置有i-1种选择. (二)对于剩下的i-1个元素,选择其中的一个元素k.这时候k有两种选择: 1. 放在第i个元素的位置上,宏观上相当于i与k的位置互换了.而剩下的i-2个元素依然要求错位排列. 2. 不放在第i个元素的位置上,则相当于剩下

算法入门经典-第七章 例题7-2-2 可重集的排列

可重:如果问题变成输入数组p,并按字典序输出数组A个元素的所有全排列,则需要修改代码集的全排列 // Rujia Liu #include<cstdio> #include<algorithm> using namespace std; int P[100], A[100]; // 输出数组P中元素的全排列.数组P中可能有重复元素 void print_permutation(int n, int* P, int* A, int cur) { if(cur == n) { for(

例题10-15 杆子的排列 UVa1638

1.题目描述:点击打开链接 2.解题思路:本题通过寻找递推关系解决.设d(i,j,k)表示让高度为1~i的杆子排成一行,从左边能看到j根,从右边能看到k根的方案数.如果开始按照从小到大把1~i-1根杆子排好了,那么高度为i的杆子可能会挡住许多杆子,很难写递推式.此时不妨换一个角度考虑:按照从大到小的顺序排列各个杆子.假设已经完成高度为2~i的杆子,那么高度为1的杆子不管放到哪里都不会挡住任何一根杆子.此时有如下三种情况: (1)插到最左边,则从左边能看到它,从右边看不到它.(因为i≥2),方案数

0x50 动态规划(0x5C 计数类DP)例题3:装饰围栏(题解)(计数类DP讲解,确定第k个排列)

计数类DP一般就是确定DP状态,DP出排名范围,然后不断逼近. 题意 题目链接 [题目描述] 有 N 块长方形的木板,长度分别为1,2,-,N,宽度都是1. 现在要用这 N 块木板组成一个宽度为 N 的围栏,满足在围栏中,每块木板两侧的木板要么都比它高,要么都比它低. 也就是说,围栏中的木板是高低交错的. 我们称"两侧比它低的木板"处于高位,"两侧比它高的木板"处于低位. 显然,有很多种构建围栏的方案. 每个方案可以写作一个长度为N的序列,序列中的各元素是木板的长度

acm常见算法及例题

转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题 初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法