let min_cut s =
  let n = String.length s in
  if n <= 1 then 0
  else begin
    let is_pal = Array.init n (fun _ -> Array.make n false) in
    for i = 0 to n - 1 do is_pal.(i).(i) <- true done;
    for len = 2 to n do
      for i = 0 to n - len do
        let j = i + len - 1 in
        if s.[i] = s.[j] then begin
          if len = 2 then is_pal.(i).(j) <- true
          else is_pal.(i).(j) <- is_pal.(i + 1).(j - 1)
        end
      done
    done;
    let cuts = Array.make n 0 in
    for i = 0 to n - 1 do
      if is_pal.(0).(i) then cuts.(i) <- 0
      else begin
        let best = ref i in
        for j = 1 to i do
          if is_pal.(j).(i) then begin
            let c = cuts.(j - 1) + 1 in
            if c < !best then best := c
          end
        done;
        cuts.(i) <- !best
      end
    done;
    cuts.(n - 1)
  end

;;

min_cut "aabba"
