12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人 高,问排列方式有多少种?

来源:互联网 发布:网络教师兼职平台 编辑:程序博客网 时间:2024/04/30 02:48
12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第一排比对应的第二排的人高,问排列方式有多少种?

思想:分析一下排列法,发现:每次安插第二排时,只要等第一排的选完了,再选最小值就行了。而选第一排时,只能从上次选的后一个开始选,且最后至少留count-1个数,count当前还剩多少个位置要安插!

//============================================================================// Name        : arrange12men.cpp// Author      : // Version     :// Copyright   : // Description : Hello World in C++, Ansi-style//============================================================================#include <iostream>#include <algorithm>#include <utility>#include <cstdio>using namespace std;void pr_arrByAux(int arr[], int len, int aux[]){int i = 0;printf("\n(1): ");for (i = 0; i < len; i++)if (aux[i] == 1)printf("%-4d", arr[i]);printf("\n(2): ");for (i = 0; i < len; i++)if (aux[i] == 2)printf("%-4d", arr[i]);printf("\n");}//把第一个为0的数放在队列2中,并返回当前位置int set2(int aux[], int len,int lastI2){int i = lastI2+1;for (; i < len; i++)if (aux[i] == 0){aux[i] = 2;return i;}return -1;}//找到可以放到队列1的第一个位置int findFirst1(int aux[], int len, int lastIndex){int i=-1;for (i = lastIndex + 1  ; i < len && aux[i]!=0; i++);return i;}/*安插队列1 * count表示还有几个人安插,lastI1表示上次安插的位置,pout表示共用多少种安插法 * lastI2表示上次安插队列2的位置 */void arrange1(int s[], int len, int count, int aux[], int lastI1,int lastI2,int *pout){if (count == 0){pr_arrByAux(s, len, aux);++*pout;return;}int f1 = findFirst1(aux, len, lastI1);for (int i = f1; i <= len - count; i++){aux[i] = 1;int j = set2(aux, len,lastI2);arrange1(s, len, count - 1, aux, i,j,pout);aux[i] = 0;aux[j] = 0;}}int arrange(int *s, int len){int sum=0;int *aux = new int[sizeof(int) * len]();aux[0]=2;arrange1(s, len, 6, aux, 0, 0,&sum);return sum;}int main(){int s[] ={ 1, 2, 3, 5, 6, 67, 23, 56, 87, 34, 32, 45 };int len = sizeof(s) / sizeof(*s);sort(s, s + len);int sum=arrange(s,len);cout << endl << "总数:" << sum << endl;return 0;}

总数为:132种