动态规划方程:dp[i][j] = (s[i]==s[j]) && (j-i<3 || dp[i+1][j-1])。
dp[i][j]表示索引i-j的串是否为回文串;s[i],s[j]表示索引上的字符。若dp[i+1][j-1]为回文串,且s[i],s[j]相等,那么dp[i][j]一定为回文串。 j-i<3,为边界条件(j-1-(i+1)-1<2),表示此时除去i和j处字符的长度,若满足这个条件,那么dp[i][j]也一定为回文串。
注意:需要j>i,这时才能构成串。

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String str= sc.next();
            System.out.println(parseStr(str));
        }
    }

    //实际方法,返回最长回文串的长度
    public static int parseStr(String str){
        int len = str.length();
        if(len < 2) return len;
        int maxLength = 0; // 保存最大长度
//         int start = 0; //起始索引
        //创建dp[][],并初始化
        boolean[][] dp = new boolean[len][len];
        for(int i = 0; i < len; i++){
            dp[i][i] = true;
        }
        //开始递推dp[][]
        //根据动态规划方程,先计算列,再计算行
        for(int j = 1; j < len; j++){
            for(int i = 0; i < j; i++){
                if(str.charAt(i) == str.charAt(j)){
                    if(j-i<3){
                        dp[i][j] = true;
                    }else{
                        dp[i][j] = dp[i+1][j-1];
                    }
                }else{
                    dp[i][j] = false;
                }
                //判断是否为回文串,更新最大长度
                maxLength = (dp[i][j] == true && j-i+1 > maxLength)? j-i+1:maxLength;
            }
        }
        return maxLength;
    } 
}