UVA删除回文串.java 1.3 KB
Newer Older
qq_36480062's avatar
c  
qq_36480062 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
package dp.区间dp;

import java.util.Arrays;
import java.util.Scanner;

/**
 * 给定一个字符串,问有几种删字符的方案使得它变为回文串。
 * 可以删掉B、BA、 AB、两个A、不删。5种
 * 字符串长度≤5000
 * 实际上统计该串有多少个回文子序列
 * f[i,j]表示Si~Sj范围内的回文串个数
 * 转移考虑last
 * S[i]==S[j]那么要统计f[i+1][j]和f[i][j-1]
 * 虽然会把f[i+1,j-1]统计两次,
 * 但是f[i+1,j-1]中的回文串可以加上S[i]和S[j]再形成f[i+1][j-1]个回文串
 * f[i,j]=f[i+1,j]+f[i,j-1]+1
 */
public class UVA删除回文串 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        s = sc.next().toCharArray();
        n = s.length;
        for (int i = 0; i < f.length; i++) {
            Arrays.fill(f[i], -1);
        }
        System.out.println(dp(0, n - 1));
        System.out.println(f[0][n - 1]);
    }

    static int dp(int l, int r) {
        if (l == r) return 1;
        if (l > r) return 0;
        if (f[l][r] != -1) return f[l][r];
        if (s[l] == s[r]) return f[l][r] = dp(l, r - 1) + dp(l + 1, r) + 1;
        else return f[l][r] = dp(l, r - 1) + dp(l + 1, r) - dp(l + 1, r - 1);
    }

    static int n;
    static char[] s;
    static int[][] f = new int[5100][5010];
}