Чтобы переводить из 10-ой системы счисления в любую из меньших нужно делить столбиком нацело. Если нацело не получается, то берется самый большой делитель и записывается, а разность делимого и произведения делителя с номером нашей системы счисления является последним числом нашего (в данном случае двоичного) числа. После этих преобразований повторяем действие, но уже делимым будет наш предыдущий делитель. Повторять нужно до тех пор, пока делитель не будет равен нулю. Пример: 12₁₀ -> X₂ 12 | 2 - | 12 | 6 | 2 - | 0 6 | 3 | 2 --- - | 0 2 1 | 2 --- - | 1 0 0
1
Помним, что записывать число нужно в обратном порядке, то есть наше число X будет равно 1100₂
function getTotalCost(firstCost,secondCost,fullUnits:real):real; begin var couponSum:=fullUnits*DISCOUNT_PER_UNIT; var secondCostWithDiscount:= secondCost-Min(MAX_DISCOUNT*secondCost,couponSum); Result:=firstCost+secondCostWithDiscount end;
function solveKnapsack(weights:array of integer; totalWeight:integer): array of integer; begin var maxUnits:=Trunc(totalWeight/cunit+1); var old:=ArrFill(maxUnits+1,totalWeight); old[0]:=0; var cur:=new integer[maxUnits+1]; var n:=weights.Length; for var pos:=0 to n-1 do begin cur.Fill(t->totalWeight); for var units:=0 to maxUnits do begin cur[units]:=Min(cur[units],old[units]); var add:=Trunc(weights[pos]/cunit); if units-add >= 0 then cur[units]:=Min(cur[units],old[units-add]+weights[pos]) end; cur.CopyTo(old,0); end; Result:=old; end;
function getSolution(costs:array of integer):real; begin var n:=costs.Length; var totalCost:=0; for var i:=0 to n-1 do totalCost+=costs[i]; var minForUnits:=solveKnapsack(costs,totalCost); Result:=totalCost; var maxUnits:=Trunc(totalCost/cunit+1); for var units:=0 to maxUnits do begin var cur:real:=minForUnits[units]; Result:=Min(Result,getTotalCost(minForUnits[units],totalCost-cur,units)) end end;
begin Writeln(getSolution(ReadArrInteger(ReadInteger)):0:2) end.