整数拆分问题

1 = 1;
 
2 = 2;
2 = 1 + 1;
 
3 = 3;
3 = 2 + 1;
3 = 1 + 1 + 1;
 
4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;
 
5 = 5;
5 = 4 + 1;
5 = 3 + 2:
5 = 3 + 1 + 1;
5 = 2 + 2 + 1;
5 = 2 + 1 + 1 + 1;
5 = 1 + 1 + 1 + 1 + 1;

6 = 6;
6 = 5 + 1;
6 = 4 + 2;
6 = 4 + 1 + 1;
6 = 3 + 3
6 = 3 + 2 + 1;
6 = 3 + 1 + 1 + 1;
6 = 2 + 2 + 2;
6 = 2 + 2 + 1 + 1;
6 = 2 + 1 + 1 + 1 + 1;
6 = 1 + 1 + 1 + 1 + 1 + 1;

在5的式子中,以5开头的式子有1个,4开头的式子有1个,三开头的式子有2个,2开头的式子有2个,1开头的式子有1个;
实际上如果以4开头,则剩下1(5-4)将被分割,1只有一种分割情况(1 =1),所以4开头的式子有1个;
同样,3开头的情况,剩下2(5-3)将被分割,2有两种分割情况(2 =2; 2 = 1 + 1;),所以3开头的式子有2个;
但是,2开头的情况有点不同,因为剩下3将被分割,但是3有3种分割式子,我们发现其中一种分割情况是将3分割成 3 = 3;
如果将这种情况算入2开头的式子总数,(式子就会变成这样5 = 2 + 3),这会违反我们开头的约定(递减排列加数),所以我们将这一条式子去掉;
同理,1开头的情况,只有一种情况,这是4的分割方法去掉所有加数大于1的式子数目得到的,但是我们也可以直接得出1,因为 这种情况太简单,我们可以直接得出结论。

通过分析我们可以得出一个式子当k小于的n时候:

 f(n,k)=f(n,k-1)+f(n-k,k)      //重点式子;
 举个例子:f(6,4)的划分可以看做是f(6,3)的划分
 再加上f(2,4)即(f(2,2))的划分。
 
 当k等于n的时候f(n,k)=f(n,k-1)+1;
 最后还有就是f(n,1)=1;
 
 这样我们就可以产生一个递推的关系式。。。。。
 用函数这样表示:
 int init(int n,int m)
{
    if(n==1||m==1)
        return 1;
    else if(n==m)
        return init(n,n-1)+1;
    else
        return init(n,m-1)+init(n-m,n-m);
}

这样我们也可以用一个数组计算并保存
int n[N][N];
void init(){
    int i,j;
    for(i=0;i<N;i++)
        n[i][1]=n[1][i]=1;
    for(i=2;i<N;i++){
        for(j=2;j<N;j++){
            if(i>j)
                n[i][j]=n[i][j-1]+n[i-j][j];
            else if(i==j)
                n[i][j]=1+n[i][j-1];
            else
                n[i][j]=n[i][i];
        }
    }
}
其中f(n,n)=n[n][n];
这样用于多输出也比较方便一些.......

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值