如果理解成以下的话,将是非常简单,不知理解是否有问题:
从 1到N 这N个数中取出某一些数,这些数的和为 M
function getSumItem(N,M,Index:integer;var Its:Array of integer):Integer;
begin
Result:=0;
//开始就 M 比 N 小,没有意义还用算吗,
// 1,2 不能分解,大于1的,1+(M-1)
if (Index=1) and (m<=n) then
begin
if M<3 then
exit;
Result:=2;
Its[1]:=1;
Its[2]:=M-1;
exit;
end;
//其实这种情况不可能,还是判断一下
if m<1 then
exit;
//全部加起来都不够,不用算了
if m>((n+1)*n div 2) then
exit;
if N>=m then
//和比最大项小,直接取这外和数就可以
begin
Its[Index]:=m;
Result:=Index;
end
else
begin
Its[Index]:=N;
//把最大项取出来,前面的和总能等于 M-N
Result:=getSumItem(N-1,m-N,Index+1,Its);
end;
end;
// 其实哪用得着递归
function getSumItemSimple(N,M:integer;var Its:Array of integer):Integer;
var
i,j,Sum:integer;
begin
Result:=0;
sum:=(((n+1)*n) shr 1);
if (m<=2) or (m>Sum) then
exit;
if m<=n then
begin
result:=2;
Its[1]:=1;
Its[2]:=M-1;
exit;
end;
Sum:=0;
j:=0;
for i:=ndo
wnto 1do
begin
inc(j);
if i<(m-sum) then
begin
Sum:=Sum+i;
Its[j]:=i;
end
else
begin
Its[j]:=M-Sum;
break;
end;
end;
Result:=j;
end;
const MaxN=1000;
function showSumItem(N,m:integer;Simple:Boolean):string;
var
x:array[0..MaxN] of integer;
i,K:integer;
s:string;
begin
for i:=1 to high(x)do
x:=0;
if simple then
k:=getSumItemSimple(n,m,x)
else
k:=getSumItem(n,m,1,x);
if k=0 then
s:='和太大,或和小于3。无解!'
else
begin
s:=Format('分解为 %d 项:%d',[k,x[1]]);
for i:=2 to kdo
s:=s+Format('+%d',[x]);
end;
Result:=s;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Showmessage(showSumItem(10,15,false));
Showmessage(showSumItem(10,15,true));
Showmessage(showSumItem(10,2,false));
Showmessage(showSumItem(10,2,true));
Showmessage(showSumItem(10,100,false));
Showmessage(showSumItem(10,100,true));
Showmessage(showSumItem(100,1000,false));
Showmessage(showSumItem(100,1000,true));
end;