Perm排列&&整数划分问题
Perm全排列
设R={r1,r2,…,rn}是要排列的n个元素,Ri=R-{ri}.集和X中的元素全排列记为Perm(X)。(ri)Perm(X)表示在全排列Perm(X)的每个排列前加上一个前缀ri得到的排列。
当n=1时,Perm(X)=®,其中r是集和R中唯一的元素
当n>1时,Perm(X)由(r1)Perm(R1),(r2)Perm(R2),…,(rn)Perm(Rn)构成
关键代码:
template <class Type>
void Perm(Type list[], int k, int m){
if(k==m){//只剩下一个元素
for(int i=0; i<=m; i++)
cout<<list[i];
cout<<endl;
}
else{//还有多个元素待排列,递归产生排列
for(int i=k; i<=m; i++){
Swap(list[k],list[i]);
Perm(list, k+1, m);
Swap(list[k], list[i]);
}
}
}
template <class Type>
inline void Swap(Type & a, Type & b){//内联交换函数
Type temp = a;
a = b;
b = temp;
}
运行代码:
# include <iostream>
using namespace std;
int p = 0;
template <class Type>
inline void Swap(Type & a, Type & b);
template <class Type>
void Perm(Type list[], int k, int m){
if(k==m){//只剩下一个元素
for(int i=0; i<=m; i++)
cout<<list[i];
p++;
cout<<endl;
}
else{//还有多个元素待排列,递归产生排列
for(int i=k; i<=m; i++){
Swap(list[k],list[i]);
Perm(list, k+1, m);
Swap(list[k], list[i]);
}
}
}
template <class Type>
inline void Swap(Type & a, Type & b){//内联交换函数
Type temp = a;
a = b;
b = temp;
}
int main(){
int list[100];
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>list[i];
}
Perm(list,0,n-1);
cout<<"全排列共有:"<<p<<"种";
return 0;
}
运行结果:
4
1 2 3 4
1234
1243
1324
1342
1432
1423
2134
2143
2314
2341
2431
2413
3214
3241
3124
3142
3412
3421
4231
4213
4321
4312
4132
4123
全排列共有:24种
整数划分问题
将正整数n表示成一系列正整数之和:n=n1+n2+…+nk(n1 ≥ \geq ≥n2 ≥ \geq ≥… ≥ \geq ≥nk ≥ \geq ≥1,k ≥ \geq ≥1).
例如,正整数6有11种划分,p(6)=11.
q
(
n
,
m
)
=
{
1
n
=
1
,
m
=
1
q
(
n
,
n
)
n
<
m
1
+
q
(
n
,
n
−
1
)
n
=
m
q
(
n
,
m
−
1
)
+
q
(
n
−
m
,
m
)
n
>
m
>
1
q(n,m)=\begin{cases}1\quad n=1,m=1\\ q(n,n)\quad n<m\\ 1+q(n,n-1)\quad n=m\\ q(n,m-1)+q(n-m,m)\quad n>m>1\\ \end{cases}
q(n,m)=⎩⎪⎪⎪⎨⎪⎪⎪⎧1n=1,m=1q(n,n)n<m1+q(n,n−1)n=mq(n,m−1)+q(n−m,m)n>m>1
递归代码
int q(int n, int m){
if((n<1)||(m<1))
return 0;
if((n==1)||m==1)
return 1;
if(n<m)
return q(n,n);
if(n==m)
return q(n,m-1)+1;
return q(n,m-1)+q(n-m,m);
}
运行代码
# include <iostream>
using namespace std;
int q(int n, int m){
if((n<1)||(m<1))
return 0;
if((n==1)||m==1)
return 1;
if(n<m)
return q(n,n);
if(n==m)
return q(n,m-1)+1;
return q(n,m-1)+q(n-m,m);
}
int main(){
cout<<"请输入要划分的整数:";
int n;
cin>>n;
cout<<"共有"<<q(n,n)<<"种划分";
return 0;
}
运行结果
请输入要划分的整数:6
共有11种划分