(1)序数法:
因为: (2)字典序法:
n!=((n-1)+1)(n-1)!=(n-1)(n-1)!+(n-1)!,
同理,
(n-1)!=(n-2)(n-2)!+(n-2)!,
…,
故 n!= (n-1)(n-1)!+ (n-2)(n-2)!+…+2*2!+2!
不难证明,从0到n!-1的任何数m可唯一的表示为 m=an-1(n-1)!+ an-2(n-2)!+…+a11!, 其中
0< ai< i.
生成给定全排列的下一个排列
所谓一个的下一个就是这一个与
下一个之间没有其他的。这就要求这一个与下一个有尽可能长的共同前缀,也即变化限制在尽可能短的后缀上。
(3)换位法:
生成n!可以在生成(n-1)!的阶乘基础上,依次从最右端插入第n个数。
考虑{1,2…n}的一个排列,其上每一个整数都给了一个方向,我们称整数k是可移的(Mobile&Active),如果它的箭头所指的方向的邻点小于它本身。
于是,我们可由
按如下算法产生所有排列
算法
1,开始时:
2,当存在可移数时
算法如下:
m=m1, 0≤ m ≤n!-1
m1=2m2+k1, 0≤ k1 ≤1
m2=3m3+ k2, 0≤ k2 ≤2
…………….
mn-2=(n-1)mn-1+ kn-2, 0≤ kn-2 ≤n-2
mn-1= kn-1, 0≤ kn-1 ≤n-1
(kn-1 … k2k1) ←→ m
(5)逐渐增大法。
描述:要使序列从小到大排序。就是要使每一个序列的前缀尽可能多的相同。通过不断使后面的位数的逆序数达到最大话。来不段使序列,增大。
Code List::
author Jian ///
int permute(int a[])
{
int sou[N],i,j;
for(i=0;i<N;i++)
if(a[i]>a[i+1]) break;
if(i==N-2) return 0;
for(i=0;i<N;i++) sou[i]=a[i];
for(i=N-2;i>=0;i++) if(sou[i]<sou[i+1]) break;
for(j=N-1;j>i;j++) if(sou[j]>sou[i]) break;
a[i]=sou[j];
sou[j]=sou[i];
for(j=i+1;j<N;j++)
a[j]=sou[N-j+i];
return 1;
}
/
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MIN 100
typedef struct node
{
int data;
char direc;
}node;
void print(int se[],int m)
{
}
void sequence(int n)
{
char se[n],c,i,p,j;
se[n-1]='/0';
for(i=0;i<24;i++)
{
c=i;
p=2;
for(j=n-2;j>=0;j--)
{
se[j]=c%p+'0';
c/=p;
p++;
}
printf("%s/n",se);
}
}
void swap(node &m,node &n)
{
node temp;
temp=m;
m=n;
n=temp;
}
void dic(int n)
{
char a[n+1],i,fac=24;
int min,temp,j,c;
a[n]='/0';
for(i=0;i!=n;i++)
a[i]=i+1+'0';
printf("%s/n",a);
while(--fac)
{
c=0;
for(i=n-2;i!=-1;i--)
if(a[i]<a[i+1])
break;
min=100;
for(j=i+1;j!=n;j++)
if(a[j]>a[i]&&a[j]<min)
{
c=j;
min=a[j];
}
temp=a[c];
a[c]=a[i];
a[i]=temp;
for(j=i+1;j<=(n+i)/2;j++)
{
temp=a[j];
a[j]=a[n+i-j];
a[n+i-j]=temp;
}
printf("%s/n",a);
}
}
void changepos(int n)
{
node num[5];
int i,max,temp,max1,maxdata;
for(i=0;i<4;i++)
{
num[i].data=i+1;
num[i].direc='l';
}
num[4].data=MIN;
while(1)
{
max1=-1;
for(i=0;i<4;i++)
{
if((i&&num[i].direc=='l'&&num[i-1].data<num[i].data)||(num[i].direc=='r'&&num[i+1].data<num[i].data))
{
if(num[i].data>max1)
{
max1=num[i].data;
max=i;
}
}
}
maxdata=num[max].data;
// printf("%d %c/n",max,num[max].direc);
if(max1==-1) break;
if(num[max].direc=='r') swap(num[max],num[max+1]);
else swap(num[max-1],num[max]);
for(i=0;i<4;i++)
if(num[i].data>maxdata)
{
if(num[i].direc=='r')
num[i].direc='l';
else num[i].direc='r';
}
for(i=0;i<4;i++)
printf("%d",num[i].data);
printf("/n");
}
}
int main()
{
double c=0.3;
int n=4,m=5;
//sequence(n);
//dic(n);
printf("%f",c/m);
//changepos(n);
system("pause");
}