区间型动态规划

  1. 给定一个序列/ 字符串,进行一些操作
  2. 最后一步将序列/字符串去头/去尾
  3. 剩下的会是一个区间[I,j]
  4. 状态自然定义为f[i][j], 表示面对子序列[I…j] 时的最优性质
  5. 667. 最长的回文序列
  6. 中文English
  7. 给一字符串 s, 找出在 s 中的最长回文子序列的长度. 你可以假设 s 的最大长度为 1000.
  8. Example
  9. 样例1
  10. 输入: "bbbab"
  11. 输出: 4
  12. 解释:
  13. 一个可能的最长回文序列为 "bbbb"
  14. 样例2
  15. 输入: "bbbbb"
  16. 输出: 5

public class Solution {

/**

* @param s: the maximum length of s is 1000

* @return: the longest palindromic subsequence's length

*/

public int longestPalindromeSubseq(String s) {

// write your code here

char[] ch = s.toCharArray();

if(ch.length==0) {

return 0;

}

int[][]dp = new int[ch.length][ch.length];

int i,j;

for(i=0;i<ch.length;++i) {

dp[i][i] = 1;

}

for(i=0;i<ch.length-1;++i) {

dp[i][i+1] = ( (ch[i]==ch[i+1])? 2:1);

}

int len;

for(len=3;len<=ch.length;++len) {

//0----len n-len ----len

for(i=0;i<=ch.length-len;++i) {

j = i+len-1;

dp[i][j] = Math.max(dp[i][j-1],dp[i+1][j]);

if(ch[i]==ch[j]) {

dp[i][j] = Math.max(dp[i][j],dp[i+1][j-1]+2);

}

}

}

return dp[0][ch.length-1];

}

}

使用记忆化搜索

public class Solution {

/**

* @param s: the maximum length of s is 1000

* @return: the longest palindromic subsequence's length

*/

public int longestPalindromeSubseq(String s) {

// write your code here

ch = s.toCharArray();

int n = ch.length;

if(n<=1) return n;

dp = new int[n][n];

int i,j;

for(i=0;i<n;++i) {

for(j=i;j<n;++j) {

dp[i][j] = -1;

}

}

dfs(0,n-1);

return dp[0][n-1];

}

char[]ch = null;

int[][]dp = null;

public void dfs(int i,int j) {

if(dp[i][j] != -1) return;

if(i==j) {

dp[i][j] = 1;

return;

}

if(i+1==j) {

dp[i][j] = (ch[i]==ch[j]) ? 2:1;

return;

}

dfs(i,j-1);

dfs(i+1,j);

dfs(i+1,j-1);

dp[i][j] = Math.max(dp[i][j-1],dp[i+1][j]);

if(ch[i]==ch[j]) {

dp[i][j] = Math.max(dp[i][j],dp[i+1][j-1]+2);

}

}

}

原文地址:https://www.cnblogs.com/lyr-2000/p/13061730.html