Done!
//仅考虑了结果的组合,而不是排列
//注:TBuffer类的代码请看 http://www.delphibbs.com/delphibbs/dispq.asp?lid=968511
function GetArrayBalls(A:array of Integer;
ArrayLen, MaxNumPerGrp, TotalNum:Integer):Integer;
var
Used:array of array of Boolean;
UsedNum:array of Integer;
Buffer:TBuffer;
proceduredo
Level(Level,StartLevel,StartPos:Integer);
var
i,j,s:Integer;
mstr:String;
begin
if Level=TotalNum then
begin
Inc(Result);
mstr:='';
for i:=0 to ArrayLen-1do
for j:=0 to A-1do
if Used[j] then
mstr:=mstr+Char(Byte('a')+i)+IntToStr(j)+' ';
mstr:=mstr+#13#10;
Buffer.WriteBuf(@mstr[1],Length(mstr));
exit;
end;
for i:=StartLevel to ArrayLen-1do
begin
if i=StartLevel then
s:=StartPos
else
s:=0;
for j:=s to A-1do
if (UsedNum<MaxNumPerGrp) and (UsedNum<A) then
begin
Inc(UsedNum);
Used[j]:=true;
do
Level(Level+1,i,j+1);
Used[j]:=false;
Dec(UsedNum);
end;
end;
end;
var
i:Integer;
begin
Result:=0;
SetLength(Used,ArrayLen);
for i:=0 to ArrayLen-1do
begin
SetLength(Used,A);
FillChar(Used[0],A*SizeOf(Boolean),0);
end;
SetLength(UsedNum,ArrayLen);
FillChar(UsedNum[0],ArrayLen*SizeOf(Integer),0);
Buffer:=TBuffer.Create;
do
Level(0,0,0);
Form1.Memo1.Text:=Buffer.AsString;
Buffer.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
A:array of Integer;
i:Integer;
begin
SetLength(A,SpinEdit3.Value);
//SpinEdit3.Value=4 分组个数
for i:=0 to SpinEdit3.Value-1do
A:=StrToInt(StringGrid1.Cells[0,i+1]);
//eg: A=(5,4,2,4)
Caption:=IntToStr(GetArrayBalls(A,SpinEdit3.Value,SpinEdit1.Value,SpinEdit2.Value));
//eg: GetArrayBalls(A,4,3,7);
4:分组个数 3:每组中最多可以被选取的球数 7:要取的总球数
end;
实验结果: 5460个解
a0 a1 a2 b0 b1 b2 c0
a0 a1 a2 b0 b1 b2 c1
a0 a1 a2 b0 b1 b2 d0
...
...
b2 b3 c0 c1 d0 d1 d2
b2 b3 c0 c1 d0 d1 d3
b2 b3 c0 c1 d0 d2 d3
b2 b3 c0 c1 d1 d2 d3
由于这个问题属于排列组合问题,解的个数会随着ArrayLen, MaxNumPerGrp, TotalNum的增长而
急剧上升。一般说来,当ArrayLen>10的时候,就已经不可计算了。
满意否?