Примерно так:
Код:
type
TDistrib = (PROP,FIRST,LAST);
TSumCollect = array of single;
function Distrib(aType:TDistrib;Sum:Single;aCollection:TSumCollect):TSumCollect;
var
i:integer;
AllSumm:single;
begin
SetLength(Result,Length(aCollection));
FillChar(Result,SizeOf(Single)*Length(Result),#0);
case aType of
FIRST:
begin
i:=Low(aCollection);
While (Sum>0) and (i<High(aCollection)) do
if Sum>aCollection[i] then
begin
Result[i]:=aCollection[i];
Sum:=Sum-aCollection[i];
inc(i)
end
else
begin
Result[i]:=Sum;
Sum:=0;
end;
end;
LAST:
begin
i:=High(aCollection);
While (Sum>0) and (i>Low(aCollection)) do
if Sum>aCollection[i] then
begin
Result[i]:=aCollection[i];
Sum:=Sum-aCollection[i];
dec(i)
end
else
begin
Result[i]:=Sum;
Sum:=0;
end;
end;
PROP:
begin
AllSumm:=0;
for i:=Low(aCollection) to High(aCollection) do
AllSumm:=aCollection[i]+AllSumm;
for i:=Low(aCollection) to High(aCollection) do
Result[i]:=Sum*(aCollection[i]/AllSumm);
end;
end; {of case}
end;
В работе не проверял, вроде компилится

Не уверен я в выделенных сравнениях, "плавающие" так не сравниваются. Но т.к. уже час ночи а завтра на работу - дорабатывайте сами
