program Polygon_DP_N3; const minVert = 3; maxVert = 50; antMaxVert = maxVert - 1; opSum = 't'; type polygonT = record vert: array[0..antMaxVert] of char; side: array[0..antMaxVert] of integer; numVert: minVert..maxVert end; maxminT = record maxVal, minVal: integer end; memoryT = array[1..maxVert, 0..antMaxVert] of maxminT; scoresT = record scor: array[1..maxVert] of integer; numVert, highScor, firstVertHS: integer; end; var fileIn, fileOut: text; polygon: polygonT; scores: scoresT; procedure ReadPolygon (var F: text; var P: polygonT); var i: integer; c: char; begin with P do begin readln(F, numVert); for i := 0 to numVert - 2 do read(F, vert[i], side[i], c); read(F, vert[numVert - 1], side[numVert - 1]); end end; procedure Evaluate (Op: char; E1, E2: maxminT; var MM: maxminT); var values: array[1..4] of integer; i, indMax, indMin: integer; begin if Op = opSum then begin MM.maxVal := E1.maxVal + E2.maxVal; MM.minVal := E1.minVal + E2.minVal end else begin values[1] := E1.maxVal * E2.maxVal; values[2] := E1.maxVal * E2.minVal; values[3] := E1.minVal * E2.maxVal; values[4] := E1.minVal * E2.minVal; indMax := 1; indMin := 1; for i := 2 to 4 do if values[i] > values[indMax] then indMax := i else if values[i] < values[indMin] then indMin := i; MM.maxVal := values[indMax]; MM.minVal := values[indMin] end end; procedure CompScores (var P: polygonT; var M: memoryT); var lastVert, line, inf, infRight, dimLeft: integer; mmTemp, mmAux: maxminT; begin lastVert := P.numVert - 1; (* Line 1 --- expressions with one integer *) for inf := 0 to lastVert do begin M[1, inf].maxVal := P.side[inf]; M[1, inf].minVal := P.side[inf] end; (* Line 2 --- expressions with two integers *) for inf := 0 to lastVert do begin infRight := (inf + 1) mod P.numVert; if P.vert[infRight] = opSum then M[2, inf].maxVal := M[1, inf].maxVal + M[1, infRight].maxVal else M[2, inf].maxVal := M[1, inf].maxVal * M[1, infRight].maxVal; M[2, inf].minVal := M[2, inf].maxVal end; (* Line 3 ... Line P.numVert *) for line := 3 to P.numVert do for inf := 0 to lastVert do begin infRight := (inf + 1) mod P.numVert; Evaluate(P.vert[infRight], M[1, inf], M[line - 1, infRight], mmTemp); for dimLeft := 2 to line - 1 do begin infRight := (inf + dimLeft) mod P.numVert; Evaluate(P.vert[infRight], M[dimLeft, inf], M[line - dimLeft, infRight], mmAux); if mmAux.maxVal > mmTemp.maxVal then mmTemp.maxVal := mmAux.maxVal; if mmAux.minVal < mmTemp.minVal then mmTemp.minVal := mmAux.minVal end; M[line, inf] := mmTemp end end; procedure CompHighScores (var P: polygonT; var S: scoresT); var mem: memoryT; i, maxScor, fstVert: integer; begin CompScores(P, mem); S.scor[1] := mem[P.numVert, 0].maxVal; maxScor := S.scor[1]; fstVert := 1; for i := 2 to P.numVert do begin S.scor[i] := mem[P.numVert, i - 1].maxVal; if S.scor[i] > maxScor then begin maxScor := S.scor[i]; fstVert := i end end; S.numVert := P.numVert; S.highScor := maxScor; S.firstVertHS := fstVert end; procedure WriteResults (var F: text; var S: scoresT); var i: integer; begin with S do begin writeln(F, highScor : 1); write(F, firstVertHS : 1); for i := firstVertHS + 1 to numVert do if scor[i] = highScor then write(F, ' ', i : 1); writeln(F) end end; begin assign(fileIn, 'POLYGON.IN'); reset(fileIn); ReadPolygon(fileIn, polygon); close(fileIn); CompHighScores(polygon, scores); assign(fileOut, 'POLYGON.OUT'); rewrite(fileOut); WriteResults(fileOut, scores); close(fileOut) end.