各位大俠, 現有一復雜題請教, 酬金1000(100分)

  • 主题发起人 主题发起人 rixin
  • 开始时间 开始时间
creation-zy: 請接分:

http://www.delphibbs.com/delphibbs/dispq.asp?lid=569337
 
creation-zy: 請接分:

http://www.delphibbs.com/delphibbs/dispq.asp?lid=570159
 
creation-zy: 請接分

http://www.delphibbs.com/delphibbs/dispq.asp?lid=570163
 
多人接受答案了。
 
改进算法:
type
CalRec=Record
Grade:Word;
Number:Integer; //成员数
UnusedNumber:Integer; //剩余的可以参加计算的成员数
Used:Boolean; //使用标志
end;
var
RecArray:array[1..MaxGrade] of CalRec; //必须保证分值从小到大
RecCount,UsedCount,BreakToCount:Integer;
procedure PrepareArray;
var
i:Integer;
begin
UsedCount:=0;
BreakToCount:=RecCount;
for i:=1 to RecCount do
with RecArray do
begin
UnusedNumber:=Number;
Used:=false;
end;
end;
procedure CalLevel(const Count,Aim,MinNumber:Integer);
var
i,m:Integer;
Str:String;
begin
if (Count<=0) and (Aim<>0) then
exit;
if (Count=0) and (Aim=0) then
begin
Str:='';
for i:=1 to RecCount do
begin
with RecArray do
begin
if Number>UnusedNumber then
begin
m:=Number-UnusedNumber;
Str:=Str+Format('%d个%d ',[m,Grade]);
if Used=false then
begin
Inc(UsedCount);
Used:=true;
end;
Dec(Number,m);
Dec(UnusedNumber,m);
if UnusedNumber<0 then
begin
if UnusedNumber=-m then //已使用元素个数=成员个数
Add_Line(Format('%d号元素成员耗尽. Grade:%d',[i,Grade]));
if BreakToCount=RecCount then //找到被耗尽的最前面一个元素
BreakToCount:=i
end;
end;
end;
end;
Add_Line(Str);
exit;
end;
for i:=MinNumber to RecCount do
begin
with RecArray do
begin
if Grade>Aim then //由于分值是依次增大的...
break;
if UnusedNumber>0 then
begin
Dec(UnusedNumber); //使用
CalLevel(Count-1,Aim-Grade,i); //以后的搜索起始层数不会比这一层小
Inc(UnusedNumber); //释放
if i>BreakToCount then //如果其前面有元素被耗尽,则退出
exit
else if i=BreakToCount then //已到达被耗尽元素处
begin
if UnusedNumber=0 then //释放完毕
BreakToCount:=RecCount
else
exit;
end;
end;
end;
end;
end;
procedure PackRecArray; //将使用过的元素从数组中剔除
var
i,j:Integer;
Str:String;
begin
with Form1.Memo1.Lines do
begin
if UsedCount>0 then
begin
Str:='';
for i:=1 to RecCount do
if RecArray.Used then
Str:=Str+IntToStr(RecArray.Grade)+' ';
Add('****** A level done! ******');
Add(Str);
Add('共减少了 '+IntToStr(UsedCount)+' 个元素');
end
else
Add('****** Found nothing in this level! ******');
end;
if UsedCount>0 then
begin
for i:=1 to RecCount-UsedCount do
if RecArray.Used then
begin //找到一个未用元素,补上
for j:=i+1 to RecCount do
if RecArray[j].Used=false then
begin
RecArray.Grade:=RecArray[j].Grade;
RecArray.Number:=RecArray[j].Number;
RecArray[j].Used:=true;
break;
end;
end;
Dec(RecCount,UsedCount);
end;
end;

与上面相同的过程已经略去。
 
后退
顶部