区间型动态规划

区间型动态规划判断:

1.去头/去尾

2.二分

667. Longest Palindromic Subsequence

https://www.lintcode.com/problem/longest-palindromic-subsequence/description?_from=ladder&&fromId=16

public class Solution {
    /**
     * @param s: the maximum length of s is 1000
     * @return: the longest palindromic subsequence's length
     */
    public int longestPalindromeSubseq(String ss) {
        // write your code here
        
        if(ss==null || ss.length()==0)
            return 0;
        
        char[] s = ss.toCharArray();
        int n = s.length;
        int f[][] = new int[n][n];
        
        for(int i=0;i<n;i++){
            f[i][i] = 1;
        }
        
        for(int i=0;i<n-1;i++){
            if(s[i]==s[i+1]){
                f[i][i+1] = 2;
            }else{
                f[i][i+1]=1;
            }
        }
        
        for(int len=3;len<=n;len++){
            for(int i=0;i<n;i++){
                int j = i+len-1;
                if(j>=n){
                    break;
                }
                
                f[i][j]= Math.max(f[i+1][j],f[i][j-1]);
                if(s[i]==s[j]){
                    f[i][j] = Math.max(f[i][j],f[i+1][j-1]+2);
                }
            }
        }
        
        return f[0][n-1];
    }
}
View Code

 记忆化搜索:递归实现

public class Solution {
    /**
     * @param s: the maximum length of s is 1000
     * @return: the longest palindromic subsequence's length
     */
    int[][]f;

    public int longestPalindromeSubseq(String ss) {
        // write your code here
        
        if(ss==null || ss.length()==0)
            return 0;
        
        char[] s = ss.toCharArray();
        int n = s.length;
        f = new int[n][n];
        
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++){
                f[i][j] = -1;
        }
        
        calc(s,0,n-1);
        return f[0][n-1];
    }
    
    public void calc(char[] s,int i,int j){
        //important
        if(f[i][j]!=-1){
            return;
        }
        
        //initialize
        if(i==j){
            f[i][j]=1;
            return;
        }
        
        if(j-i==1){
            if(s[i]==s[j]){
                f[i][j]=2;
            }else{
                f[i][j]=1;
            }
            return;
        }
        
        calc(s,i+1,j);
        calc(s,i,j-1);
        calc(s,i+1,j-1);
        
        f[i][j]= Math.max(f[i+1][j],f[i][j-1]);
        if(s[i]==s[j]){
            f[i][j] = Math.max(f[i][j],f[i+1][j-1]+2);
        }
        return;
    }
}
View Code

396. Coins in a Line III

思路:f[i][j]是指先手面对 i~j 的区间能取得的最大效益

https://www.lintcode.com/problem/coins-in-a-line-iii/description?_from=ladder&&fromId=16

public class Solution {
    /**
     * @param values: a vector of integers
     * @return: a boolean which equals to true if the first player will win
     */
    public boolean firstWillWin(int[] values) {
        // write your code here
        if(values==null || values.length==0){
            return true;
        }
        
        int n = values.length;
        int[][] f = new int[n][n];
        
        for(int i=0;i<n;i++){
            f[i][i]= values[i];
        }
        
        for(int len =2;len<=n;len++){
            for(int i=0;i<n;i++){
                int j = i+len-1;
                if(j>=n){
                    break;
                }
                f[i][j] = Math.max(values[j]-f[i][j-1],values[i]-f[i+1][j]);
            }
        }
        
        return f[0][n-1]>=0;
    }
}
View Code

430. Scramble String

思路:f[i][j][w] 是指 s1以i为起始w长度的字符串 和 s2以j为起始w长度的字符串 是否可以是攀爬字符串

https://www.lintcode.com/problem/scramble-string/description?_from=ladder&&fromId=16

public class Solution {
    /**
     * @param s1: A string
     * @param s2: Another string
     * @return: whether s2 is a scrambled string of s1
     */
    public boolean isScramble(String s1, String s2) {
        // write your code here
        if(s1 == null && s2!=null){
            return false;
        }
        
        if(s1!=null && s2==null){
            return false;
        }
        
        if(s1.length()!=s2.length()){
            return false;
        }
        
        int n = s1.length();
        boolean[][][] f = new boolean[n][n][n+1];
        
        for(int i=0;i<n;i++){
            for(int j =0;j<n;j++){
                f[i][j][1]= s1.charAt(i)==s2.charAt(j)? true:false;
            }
        }
        
        for(int len=2;len<=n;len++){
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    f[i][j][len] = false;
                    
                    for(int w=1;w<len;w++){
                        if(i+w<n && j+w<n && f[i][j][w] && f[i+w][j+w][len-w]){
                            f[i][j][len] = true;
                            break;
                        }
                        
                        if(i+w<n && j+len-w<n && f[i][j+len-w][w] && f[i+w][j][len-w]){
                            f[i][j][len] = true;
                            break;
                        }
                    }
                }
            }
        }
        
        return f[0][0][n];
        
    }
}
View Code

猜你喜欢

转载自www.cnblogs.com/lizzyluvcoding/p/10800017.html
今日推荐