文档章节

整数划分

htq
 htq
发布于 2016/07/26 09:40
字数 884
阅读 8
收藏 0
整数划分,是指把一个正整数n写成如下形式:
       n=m1+m2+...+mi; (其中mi为正整数,并且1 <= mi <= n),则{m1,m2,...,mi}为n的一个划分。
       如果{m1,m2,...,mi}中的最大值不超过m,即max(m1,m2,...,mi)<=m,则称它属于n的一个m划分。这里我们记n的m划分的个数为f(n,m);
       例如当n=4时,结果应为,{4},{3,1},{2,2},{2,1,1},{1,1,1,1};

在算法书上介绍的思路如下:

 根据n和m的关系,考虑以下几种情况:
        (1)当n=1时,不论m的值为多少(m>0),只有一种划分即{1};
         (2) 当m=1时,不论n的值为多少,只有一种划分即n个1,{1,1,1,...,1};
         (3) 当n=m时,根据划分中是否包含n,可以分为两种情况:
              1). 划分中包含n的情况,只有一个即{n};
              2). 划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有(n-1)划分。
              因此 f(n,n) =1 + f(n,n-1);
        (4) 当n<m时,由于划分中不可能出现负数,因此就相当于f(n,n);
        (5) 但n>m时,根据划分中是否包含最大值m,可以分为两种情况:
               1). 划分中包含m的情况,即{m, {x1,x2,...xi}}, 其中{x1,x2,... xi} 的和为n-m,因此这种情况下
                 为f(n-m,m)
              2). 划分中不包含m的情况,则划分中所有值都比m小,即n的(m-1)划分,个数为f(n,m-1);
              因此 f(n, m) = f(n-m, m)+f(n,m-1);
      综上所述:
                             f(n, m)=   1;                (n=1 or m=1)
                             f(n, n);                        (n<m)
                             1+ f(n, m-1);                (n=m)
                             f(n-m,m)+f(n,m-1);      (n>m)

在算法书上也给出了解决的代码,但只给出了输出结果数,具体每种情况的划分是怎样的没给出代码,本人在书上代码思路的理解和参考网上部分博客后基于自己的理解给出代码如下:

#include <iostream>  
using namespace std;  
  
//用于打印(输出)的函数  
//result为存储某划分结果的数组,length为此划分所占长度-1(从0开始)  
void display(int *result,int length)         
{     
    for(int i=0;i<length;i++)  
        cout<<result[i]<<" ";  
    cout<<endl;  
}  
  
//主划分函数q(int n,int m,int *result,int length)  
//n为待划分整数,m为最大加数上限,result和length意以同display函数  
//将q分成五种情况分类讨论,其中包含递归调用  
int q(int n,int m,int *result,int length)  
{  
//当n>=1且m=1时,q(n,m,result,length)=q(n-1,m,result,length)      
     if(n>=0&&m==1)                                                                                       
    {  
//直至n=0且m=1时,输出  
        if(n==0)   
		{
			display(result,length);  
		}  
        else  
        {  
        result[length]=1;  
        q(n-1,m,result,length+1);  
        }  
        return 1;  
    }  
// 当 n=1且m>1 时,分解已经完成,进行输出  
    else if(n==1&&m>1)                                 
    {  
        result[length]=n;  
        display(result,length+1);  
        return 1;  
    }  
  
//当n<m时,q(n,m,result,length)=q(n,n,result,length)  
    else if(n<m)                                        
   {  
        return q(n,n,result,length);  
    }  
  
//当n=m时,q(n,m,result,length)=q(n,m-1,result,length)+1(划分数目)  
    else if(n==m)                                           
{  
        result[length]=m;  
        display(result,length+1);  
        return q(n,m-1,result,length)+1;  
    }  
  
//当n>m>1时,//q(n,m,result,length)=q(n-m,m,result,length+1)+q(n,m-1,result,length)  
    else                                                           
    {  
        result[length]=m;  
        return q(n-m,m,result,length+1)+q(n,m-1,result,length);  
    }  
}  
  
  
  void main()  
  {  
      int n;                            //定义待划分整数  
      int result[100]={0},length=0;        //初始化  
      cout<<"please input the integer:";    
      cin>>n;  
      cout<<"整数"<<n<<"的划分个数为"<<q(n,n,result,length)<<endl;  
  }
程序运行结果如下:



本文转载自:http://blog.csdn.net/htq__/article/details/50857023

共有 人打赏支持
htq

htq

粉丝 19
博文 67
码字总数 1007
作品 3
武汉
私信 提问
动态规划-数的划分

数的划分有很多种,也可以列为DP的一种模型了吧 (一)数的划分 成R份(不可空) 整数N,划分成R份,每份不可空,求方法总数 【解法】分为有1和没有1两种情况 i划分成j份的方法总数是以下两种情...

binary_heap
2017/12/03
0
0
Lintcode31 Partition Array solution题解

【题目描述】 Given an array nums of integers and an int k, partition the array (i.e move the elements in "nums") such that:All elements < k are moved to the left;All elements >=......

sun511230
2017/05/19
0
0
Lintcode31 Partition Array solution题解

【题目描述】 Given an array nums of integers and an int k, partition the array (i.e move the elements in "nums") such that:All elements < k are moved to the left;All elements >=......

abcdd1234567890
2018/06/29
0
0
简单Python划分子网

给定一个私有地址网段192.168.30.0,从键盘输入需要花费的子网数,按照输入的情况自动化分子网。具体要求如下: (1)做数据规范,输入的内容必须是2-16的整数,当输入的不是数字或数字超出范...

素手蛮腰称孤
2015/10/23
238
1
Codility每周一课:L10 Prime and composite numbers(10.3)

P10.3 Peaks Divide an array into the maximum number of same-sized blocks, each of which should contain an index P such that A[P - 1] < A[P] > A[P + 1]. P10.3 峰值 将数组分为具有......

AiFan
01/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

再谈使用开源软件搭建数据分析平台

三年前,我写了这篇博客使用开源软件快速搭建数据分析平台, 当时收到了许多的反馈,有50个点赞和300+的收藏。到现在我还能收到一些关于dataplay2的问题。在过去的三年,开源社区和新技术的发...

naughty
今天
3
0
C++网络编程(一)gRPC的编译

Google是真滴烦,整个编译链全是自家产品,在编译之前先来安装一堆东西 安装环境依赖 chocolatey Windows下的包管理系统,没有他就慢慢去下载下面的一堆乱七八糟的东西吧。CMD下执行下面这句...

Pulsar-V
今天
3
0
Python3的日期和时间

python 中处理日期时间数据通常使用datetime和time库 因为这两个库中的一些功能有些重复,所以,首先我们来比较一下这两个库的区别,这可以帮助我们在适当的情况下时候合适的库。 在Python文...

编程老陆
今天
2
0
分布式面试整理

并发和并行 并行是两个任务同时进行,而并发呢,则是一会做一个任务一会又切换做另一个任务。 临界区 临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用,但是每一次,只能有...

群星纪元
今天
3
0
手机通过wifi遥控arduino

手机下载Blinker 从Blinker官网下载手机App,安装到手机。 手机连接WiFi。 点击我的设备右上角的"+"添加设备,选择Arduino -> wifi接入,复制密钥以备后续使用。 点击新建的设备,可以在新界...

davidwbnu
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部