码迷,mamicode.com
首页 > 其他好文 > 详细

整数划分方案

时间:2015-07-28 13:10:05      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

华电北风吹
天津大学认知计算与应用重点实验室
最后修改日期:2015/7/28

根据每一种划分里面最大的数进行划分。

为此,先规定我们的划分结果数字重视按照从大到小的顺序输出的比如9可以划分为1、2、2、4,我们划分时均把每一类划分最大的元素放在第一位,次大的第二位……,例如4,2,2,1。

法一:前向
为了避免重复,我们可以先对于每一种划分的第一个数进行分类有1、2、3、4……9共9类,然后对每一种类进行再次划分(比如对于第一个数字为5,就需要对5以后进行划分,不过后面分配的数不能超过第一个数。所以第一个数字为5时,第二个数字就可以取1、2、3、4,然后继续对第三个数字划分,直到最后加和为9),这时每得到的一种划分方法就是9的所有的无重复的一种划分方法。
MATLAB代码:
递归函数:

function f=func(a)
global t;       % 需要划分的数
global p;       % 记录符合条件划分次数
temp=sum(a);
k=length(a);
if k>0                             % 第一次进入递归函数进入else
   result=min([t-temp a(k)]);     % 确定本步接下来分配次数
else
   result=t-temp;
end
for i=result:-1:1
   b=[a i];
   if sum(b)==t                   % 符合输出条件的b输出
       p=p+1;
        disp([‘第‘,num2str(p),‘种划分法‘]);
       b
   else                           % 不符合输出条件的b递归
       if sum(b)
           func(b);
       end
   end
end

主函数:

clear;clc;
global t;       % 需要划分的数
global p;       % 记录符合条件划分次数
p=0;
t=input(‘输如需要划分数:‘);
a=[];
func(a);
disp(‘最终划分种类数p=‘)
p

法二:后向
从最后一位向第一位依次向前计算。方法思路跟第一种类似。但是是从后往前循环计算,如果后面k位可以划分就对后面k位进行划分,直到划分出全部为1的和结束。然后对第一位降1继续对后面划分。
MATLAB代码:

% mainfunction
clear;clc;
n=input(‘请输入n的值:‘);
if n==1
   disp(‘1=1‘);
   return;
end
if n==2
   disp(‘2=1+1‘)
   return;
end
a=zeros(1,n);
a(1)=n;     % 数组a为长度为n的一维数组
top=2;      % 指向当前分配长度下一位
k=0;        % 记录分配次数
while true
   k=k+1;
   % 输出当前满足条件的分配方案
   disp([‘第‘,num2str(k),‘种划分法‘]);
   result=[];
   for i=1:n
       if a(i)>0
           result=[result a(i)];
       end
   end
   result
   % 把数组a后面所有需要分配的数加起来,包括所有的1和一个非1
   s=0;
   while true
       top=top-1;
       s=s+a(top);
       if top>1&&a(top)==1
           continue
       else
           break;  % a(top)大于1
       end
   end             % top更新为指向最后一位大于1的数
   if a(1)==1
       break;
   end;
   % 对当前a重新分配
   d=a(top)-1;
   if d==1
       % s分到top后面每个数全为1分配
       while s>0
           a(top)=1;
           s=s-1;
           top=top+1;
       end
   else
       % s分到top后面按d分配,最后一个为余数
       while s>d
           a(top)=d;
           top=top+1;
           s=s-d;
       end
       if s~=0
           a(top)=s;
           top=top+1;
       end
   end
end

补充 当只需要知道划分个数,不需要知道方案细则的可以采用下面方案,对于divide函数由于包含很多重复计算,可以设置一个字典用来保存已经计算过的(n,m)用空间换时间

function f=divide(n,m)

if m==1||n==1
   f=1;
else
   if n<m
       f=divide(n,n);
   else
       if n==m
           f=1+divide(n,m-1);
       else
           if n>m
                f=divide(n-m,m)+divide(n,m-1);
           end
       end
   end
end

版权声明:本文为博主原创文章,未经博主允许不得转载。

整数划分方案

标签:

原文地址:http://blog.csdn.net/zhangzhengyi03539/article/details/47102345

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!