算法分析与设计学习笔记5之整数拆分问题

老规矩步入正题之前先说点儿题外话,今天老师讲的东西感觉没什么需要记录的,所以今天就把之前老师布置的一个作业拿出来分析一下吧,水一篇文章,毕竟好几天没更新了,话不多说,上题

Question

整数划分问题。把正整数n表示成一系列正整数的和,n=n1+n2+n3+...+ni,这种表示成为n的划分,不同的划分个数称为正整数n的划分数,如6有11种划分。设计算法,输出n的划分数和具体的划分方法(用递归的方法)。

Analyze

这个题目乍一看,给我的第一感觉,啥玩意啊,咋感觉云里雾里的,细看,哦,原来就是小学的一道题,大致意思就是让你将数字拆分。并输出拆分的结果和拆分的数量
比如,输入6输出
1+1+1+1+1+1
1+1+1+1+2
1+1+1+3
1+1+2+2
1+1+4
1+2+3
1+5
2+2+2
2+4
3+3
6
然后输入分类的种数为11
如果抛开问题来讲这个问题存在两种解决方法,一是使用递推来完成,二是使用递归的方法实现,递推的方法没什么好讲的,所以我就只讲递归的算法思想。
所谓递归就是程序调用自身,最常见的例子就是斐波那契函数(作者后续可能会更新一篇文章专门来讲斐波那契函数),对于这个题目我们需要定义一个函数然后让这个函数不断调用它本身完成数字拆分,我们需要将问题分成两部分来进行,一是进行运算,二是将运算出来的数据进行存储,即我们边把数据运算出来,边把数据存储到一个地方,然后将数据输出,就这样重复来使整数整个拆分开来,我空口说可能大家听起来比较晕,所以我直接上代码吧

Code

python代码实现

import sys
def divide(n, m):
    global List
    global p
    global z
    if n == 0:
        for i in range(p):
            print(List[i], end="")
            if i == p-1:
                continue
            else:
                print("+", end="")
        z += 1
        print("")
    for i in range(m, n+1):
        List[p] = i
        p += 1
        divide(n-i, i)
        p -= 1
if __name__ == '__main__':
    while(1):
        print("Please input the number you want to divide(input zero or negative exit):",end="")
        n = int(input())
        if (n < 0 or n == 0):
            print("Welcome to use next time")
            sys.exit(1)
        z = 0
        List = [0] * n
        m = 1
        p = 0
        print("The result is:")
        divide(n, m)
        print("There are %d ways to divide the number"%z)

C语言实现

# include <stdio.h>
# include <stdlib.h>
# define X 100
int z = 0;
int m = 1;
int p = 0;
int List[X];
void Divide(int n ,int m)
{
	if(n == 0)
	{
		for(int i = 0;i < p; i++)
		{
			printf("%d",List[i]);
			if(i == p-1)
				continue;
			else
				printf("+");
		}
		z++;
		printf("
");
	}
	for(int j = m; j < n+1; j++)
	{
		List[p] = j;
		p++;
		Divide(n-j, j);
		p--;
	}
}
void main()
{
	while(1)
	{
		int n;
		printf("Please input the number you want to divide(input zero or negative exit):");
		scanf("%d",&n);
		if(n < 0 || n == 0)
		{
			printf("Welcome to use next time
");
			exit(1);
		}
		for(int i = 0; i < X;i++)
		{
			List[i] = 0;
		}
		printf("The result is:
");
		Divide(n,m);
		printf("The are %d ways to divide the number
",z);
	}
}

友情提示

代码中的那个大循环我是为了能够让这个程序循环使用,如果说仅仅是单次使用可以不加,仅仅看代码可能不会很清楚,我给列为看官的建议是带上一个数字跑一下,整个过程就都明白了,在这里我就不赘述了

Verify

Python结果

C语言结果

联系我

博客园:https://www.cnblogs.com/AWSG-Shaodw/
CSDN:https://blog.csdn.net/AngleWithShotgun/
简书:https://www.jianshu.com/u/df7323cbc116

微信公众号:
export1583561150778.jpg

一笑不琅然一个专注于搞事情的的大学IT男

QQ:1009178488
原文地址:https://www.cnblogs.com/AWSG-Shaodw/p/12461275.html