Visitors hit counter dreamweaver

递归--整数划分问题

问题描述:

将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。正整数n的这种表示称为正整数n的划分。

问题1:

输出整数n的所有可能的划分,如:

输入:6

输出: 5+1;

      4+2,4+1+1;

        3+3,3+2+1,3+1+1+1;

      2+2+2,2+2+1+1,2+1+1+1+1;

      1+1+1+1+1+1。

我的思路:这种问题已经遇到过很多了,递归搜索所有可能的情况,同时为了记录下每一步的情况,那么就要用到一个数组mark来存储每一步的数,然后递归同时要传递递归的深度k。还有个问题就是递归下一个数的时候,因为是递减的排列的。所以我们还必须记录下上一个的数,然后下一个数必须小于或者等于上一个数。最后递归函数还有有个参数记录当前的长度,来判断是否能够组成我们想要的长度,不能的话就回溯,继续往下一个数去尝试。OK!

代码:

//整数划分问题
#include <stdio.h>

int mark[10];
int n;

void Divid(int now,int k,int prio)  
 {
    //now记录当前长度,k记录深度,prio记录前一个的值。
    int i;
    if(now > n) return;  //不合适,返回。
    if(now == n)
    {
        for(i = 0; i < k-1; i++)
            printf("%d+",mark[i]);
        printf("%d\n",mark[i]);
    }
    else
    {
        for(i = prio; i > 0; i--)
        {
            if(i <= prio)  //必须必前一个要小
            {
                mark[k]=i;
                now+=i;
                Divid(now,k+1,i);
                now-=i;
            }
        }
    }
 }

int main()
{
    scanf("%d",&n);
    Divid(0,0,n-1);
    return 0;
}
2013/5/29 14:17

 问题2:求正整数n的不同划分个数,将最大数n1不大m的划分记住做q(n,m),叫做n的m划分。

输入:n m

输出:n的m划分的总个数。

我的思路:首先要找出递归的公式来,首先分析几种简单的情况,n==1||m==1可以直接得出结果为1;而当n<m时,可以直接求出q(n,n);当n=m时,因为对于n本身只有一种情况,即n,所有可以直接用1+q(n,n-1)来求。最后当n>m时,可以用q(n,m-1)+q(n-m,m),其中q(n-m,m表示的时当m固定后,求剩下可能的情况。参考下图:

 

代码:

//求整数划分的个数
#include <stdio.h>

int Divid(int n, int m)
{
    if (n == 1 || m == 1) return 1;  //必须是或
    if (n < m) return Divid(n,n);
    if (n == m) return 1 + Divid(n,n-1);
    return Divid(n,m-1) + Divid(n-m,m);
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    printf("%d\n",Divid(n,m));
    return 0;
}

2013/5/29 14:35

 

posted @ 2013-05-29 14:35  Jason Damon  阅读(3611)  评论(0编辑  收藏  举报