3ms Java DP bottom-up solution
int[][] table: table[i][j] stores for substring [i, j] (inclusively), the minimum number of characters need to be changed to make the substring palindrome.\nint
int[][] table: table[i][j] stores for substring [i, j] (inclusively), the minimum number of characters need to be changed to make the substring palindrome.\nint[][] record: the dp table, record[k][n] stores the minimum number of characters need to be changed to divide the array starts with index 0 with length n into k palindroms.\n\nFor string starts at 0 index with length of n, we divide the string into two major parts:\npart1 :  k -1 palindrome slots with total length of L\npart2:  remaing tail indexing [L + 1, n - 1], we need to make it into one palindrome.\n\nThe rule is: record[k][n] = min(record[k-1][L] + table[L][n - 1] ) for every valid L.\n|<----------------n------------>|\nxxxxxxxxxxxxxxxxxxxx|**xxxxxxxx**\n|<-------L----------->|<------->|\n|<---dp[k-1][L]----->|-table[L][n-1]\n\nHere is the code:\n```\npublic int palindromePartition(String s, int k) {\n        char[] arr = s.toCharArray();\n        int n = arr.length;\n\t\t//represents the minimum number of chars, if we want to divide the string with a length n  into k slots.\n        int[][] record = new int[k + 1][n + 1];\n\t\t//the minimum number of chars, if make substring [i, j] into one palindrom.\n        int[][] table = getTable(arr);\n\t\t//k == 1 means divide into one palindrome, same as what table stores.\n        for (int i = 1; i <= n; i++) {\n            record[1][i] = table[0][i-1];\n        }\n        for (int i = 2; i <= k; i++) {\n            for (int j = i + 1; j <= n; j++) {\n                int curMin = Integer.MAX_VALUE;\n                for (int l = i-1; l < j; l++) {\n                    curMin = Math.min(curMin, record[i-1][l] + table[l][j-1]);\n                }\n                record[i][j] = curMin;\n            }\n        }\n        return record[k][n];\n    }\n\t\n    //helper function to generate table[][]\n    private int[][] getTable(char[] arr) {\n        int n = arr.length;\n        int[][] record = new int[n][n];\n        for (int i = 0; i < n; i++) {\n            for (int j = i - 1; j >= 0; j--) {\n                if (arr[j] == arr[i]) {\n\t\t\t\t\trecord[j][i] = record[j+1][i-1] + (arr[i] == arr[j]? 0 : 1);\n\t\t\t\t}\n            }\n        }\n        return record;\n    }\n```
[]