Perm排列&&整数划分问题

本文探讨了 Perm 全排列的概念,详细解释了当n=1和n>1时Perm(X)的构成,并提供了关键代码实现。此外,还介绍了整数划分问题,即如何将正整数表示为一系列正整数之和,给出了正整数6的11种划分示例,并展示了递归算法解决该问题的代码及其运行结果。
摘要由CSDN通过智能技术生成

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,n1)n=mq(n,m1)+q(nm,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种划分
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值