Problem:
Score : 900 points

Problem Statement

Takahashi has decided to give a string to his mother.

The value of a string T is the length of the longest common subsequence of T and T', where T' is the string obtained by reversing T.
That is, the value is the longest length of the following two strings that are equal: a subsequence of T (possibly non-contiguous), and a subsequence of T' (possibly non-contiguous).

Takahashi has a string S. He wants to give her mother a string of the highest possible value, so he would like to change at most K characters in S to any other characters in order to obtain a string of the highest possible value.
Find the highest possible value achievable.

Constraints

1 \leq |S| \leq 300

0 \leq K \leq |S|

S consists of lowercase English letters.

K is an integer.

Input

Input is given from Standard Input in the following format:

S
K

Output

Print the highest possible value achievable.

Sample Input 1

abcabcabc
1

Sample Output 1

7

Changing the first character to c results in cbcabcabc.
Let this tring be T, then one longest common subsequence of T and T' is cbabcbc, whose length is 7.

Sample Input 2

atcodergrandcontest
3

Sample Output 2

15

Solution in Go (1.6) (judge verdict: Memory Limit Exceeded)

package main

import (
  "bufio"
  "os"
  "strconv"
  "strings"
  "fmt"
)

var reader = bufio.NewReaderSize(os.Stdin, 1000000)
var writer = bufio.NewWriter(os.Stdout)
func NextLine() string {
  buffer := make([]byte, 0)
  for true {
    line, isPrefix, err := reader.ReadLine()
    if err != nil { panic(err) }
    buffer = append(buffer, line...)
    if !isPrefix { break }
  }
  return string(buffer)
}
func NextInt() int {
  n, _ := strconv.Atoi(NextLine())
  return n
}
func NextIntVec() []int {
  L := strings.Split(NextLine(), " ")
  N := make([]int, len(L))
  for i := range N {
    N[i], _ = strconv.Atoi(L[i])
  }
  return N
}
func NextFloat() float64 {
  n, _ := strconv.ParseFloat(NextLine(), 64)
  return n
}
func NextFloatVec() []float64 {
  L := strings.Split(NextLine(), " ")
  N := make([]float64, len(L))
  for i := range N {
    N[i], _ = strconv.ParseFloat(L[i], 64)
  }
  return N
}
func Write(s interface{}) {
  fmt.Fprintln(writer, s)
}
func WriteIntVec(A []int) {
  S := make([]string, len(A))
  for i, a := range A {
    S[i] = strconv.Itoa(a)
  }
  Write(strings.Join(S, " "))
}
func Output() {
  _ = writer.Flush()
}

func MaxInt(A ...int) int {
  max := A[0]
  for _, a := range A {
    if max < a { max = a }
  }
  return max
}

func Solve() {
  S := NextLine()
  N := len(S)
  K := NextInt()
  M := make([][]int, 26)
  for i := range M {
    M[i] = make([]int, N)
  }
  for i, s := range S {
    m := int(s) - int('a')
    M[m][i] = i + 1
  }
  for i := range M {
    for j := N - 1; 0 < j; j-- {
      if 0 < M[i][j - 1] { continue }
      M[i][j - 1] = M[i][j]
    }
  }
  DP := make([][][]int, K + 1)
  for i := range DP {
    DP[i] = make([][]int, N)
    for j := range DP[i] {
      DP[i][j] = make([]int, N)
      for k := 0; k < i + 1; k++ {
        if N <= j + k { continue }
        DP[i][j][j + k] = k + 1
      }
    }
  }
  for i := range DP {
    for j := N - 1; 0 <= j; j-- {
      for k := j + 1; k < N; k++ {
        DP[i][j][k] = MaxInt(DP[i][j][k - 1], DP[i][j][k])
        l := M[int(S[k]) - int('a')][j]
        if l <= k {
          DP[i][j][k] = MaxInt(DP[i][l][k - 1] + 2, DP[i][j][k])
        }
        if j < N - 1 {
          DP[i][j][k] = MaxInt(DP[i][j + 1][k], DP[i][j][k])
        }
        if 0 < i {
          DP[i][j][k] = MaxInt(DP[i - 1][j][k], DP[i][j][k])
          DP[i][j][k] = MaxInt(DP[i - 1][j + 1][k - 1] + 2, DP[i][j][k])
        }
      }
    }
  }
  Write(DP[K][0][N - 1])
  return
}

func main() {
  Solve()
  Output()
}