正整数分割

正整数分割

定义

分割: 将一个正整数划分为几个数的和的不同表示方法的总数。

记号

P(x,y) 表示正整数x的所有划分中,极大值不大于y的划分的总数。
例如4的所有划分: 1+1+1+1,2+1+1,2+2, 3+1,4 一共,5个,其中 P(4,2)=2
S(x,y) 表示正整数x的所有划分中,极大值不大于y的划分的加和序列集合,并且加数按递减的顺序排列。
例如 S(4,2)={1+1+1+12+1+12+2}
Set(x,y) 表示正整数x的所有划分中,极大值恰好等于y的划分的加和序列集合,并且加数按递减的顺序排列。
例如 Set(4,2)={2+1+12+2}
{x...y} 表示 Set(x,y) 中的加和序列去掉第一个y之后剩下的加和序列。
例如 {4...2}={1+12}

分析

  1. y=x 时, P(x,y)=1+P(x,x1)
  2. y>x 时, P(x,y)=P(x,x)
  3. y<x 时, P(x,y)=P(x,y1)+P(xy,y)
    证明:
    a). P(x,y1) 表示x的划分中,极大值不大于y-1的所有划分的个数,所以 P(x,y)P(x,y1) 表示x的划分中,极大值恰好等于y的划分个数,也就是 Set(x,y) 的大小。所以我们需要证明 P(xy,y)=|Set(x,y)|
    将x的划分中的各个值按递减的顺序排列,则x的划分中所有极大值恰好等于y的划分一定是形如 x=y+x...y 的形式,所以有 xy=x...y ,这就说明了 x...y x...y 是一段按大小顺序排列好了的极大值不大于y的加和序列,他加上y之后的值等于x)一定在 S(xy,y) 之中。这里所有的 x...y 构成的集合的大小就是 Set(x,y) 的大小(因为每一个 x...y 都是由 Set(x,y) 中的一个唯一的加和序列去掉第一个y得到)
    b). {x...y}=S(xy,y)
    a)可知 {x...y}S(xy,y)
    那么 S(xy,y) 是不是要比 {x...y} 大呢?,答案是否定的。
    因为,如果 S(xy,y) {x...y} 要大,那么 S(xy,y) 中必然存在一个 xy 的划分的加和序列,姑且将这个划分的加和序列(加数按递减的顺序排列)记作 p 使得 p{x...y} ,
    然而由于 xy=px=y+p , 所以 p{x...y} ,矛盾,故而 {x...y}=S(xy,y)
    所以有 P(xy,y)=|S(xy,y)|=|{x...y}|=|Set(x,y)|
    从而得到当 y<x 时, P(x,y)=P(x,y1)+P(xy,y)

图示


< header >

#include<iostream>
using namespace std;

< partitions >

/* 将一个正整数划分为几个数的和的不同表示方法的总数。 记P(x,y)表示正整数x的所有划分中,极大值不大于y的划分的总数。 例如3的所有划分:1+1+1,2+1,3 一共3个,其中P(3,2)=1 */

int partitions(int const n);
int partitions(int const x, int const y)
{
    if (y == 1) return 1;
    if (x <= y) return  partitions(x);

    return partitions(x, y - 1) + partitions(x-y,y);
}

int partitions(int const n){

    if (n == 1) return 1;

    return 1 + partitions(n,n-1);

}

< main >

int main(){

    int n;
    cout << "输入想要划分的正整数n" << endl;
    cin >> n;

    cout << partitions(n) << endl;

    system("pause");
    return 0;
}


你可能感兴趣的:(正整数分割)