算法营day14--动态规划

牛客 distinct-subsequences

题目描述
给定两个字符串S和T,返回S子序列等于T的不同子序列个数有多少个?
字符串的子序列是由原来的字符串删除一些字符(也可以不删除)在不改变相对位置的情况下的剩余字符(例如,"ACE"is a subsequence of"ABCDE"但是"AEC"不是)
例如:
S =“rabbbit”, T =“rabbit”
返回3
代码:

import java.util.*;
 
 
public class Solution {
    
    
    /**
     *
     * @param S string字符串
     * @param T string字符串
     * @return int整型
     */
    public int numDistinct (String S, String T) {
    
    
        // write code here
        int row = S.length();
        int col = T.length();
        int [][] numD = new int[row+1][col+1];
        numD[0][0] = 1;
        for(int i = 1;i<=row;++i){
    
    
            numD[i][0] = 1;
            for(int j =1;j<=col;++j){
    
    
                if(S.charAt(i-1) == T.charAt(j-1))
                    numD[i][j] = numD[i-1][j-1] + numD[i-1][j];
                else
                    numD[i][j] = numD[i-1][j];
            }
        }
        return numD[row][col];
    }
}

优化空间之后:

import java.util.*;


public class Solution {
    
    
    /**
     * 
     * @param S string字符串 
     * @param T string字符串 
     * @return int整型
     */
    public int numDistinct (String S, String T) {
    
    
        // write code here
        int row = S.length();
        int col = T.length();
        int []numD = new int[col+1];
        numD[0] = 1;
        for(int i = 1;i<=row;++i){
    
    
            for(int j =col;j>0;--j){
    
    
                if(S.charAt(i-1) == T.charAt(j-1))
                    numD[j] = numD[j-1] + numD[j];
            }
        }
        return numD[col];
    }
}

牛客 剪绳子

题目描述
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],…,k[m]。请问k[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

思路:
DP
代码:

class Solution {
    
    
public:
    int cutRope(int number) {
    
    
        //<=4的情况单独做处理
        if(number < 2)
            return 0;
        if(number == 2)
            return 1;
        if(number == 3)
            return 2;
        vector<int> dp(number+1);
        dp[0] = 0;
        //1是不可分割的,2和3分割就会变小
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
        int max = 0;
        //dp数组从下标4开始才表示:当前长度的绳子可以分割成绳子的最大积。
        for(int i = 4;i <= number;++i){
    
    
            max = 0;
            for(int j = 1; j <= i/2;++j){
    
    
                int product = dp[j] * dp[i-j];
                if(product > max)
                    max = product;
                dp[i] = max;
            }
        }
        max = dp[number];
        return max;
    }
};

思路:
贪心。当n>=5的时候,尽可能多剪长度为3的绳子;当剩下的绳子长度为4时,把绳子剪成长度为2的绳子。
代码:

class Solution {
    
    
public:
    int cutRope(int number) {
    
    
        //<=4的情况单独做处理
        if(number < 2)
            return 0;
        if(number == 2)
            return 1;
        if(number == 3)
            return 2;
        int max = 0;
        int timesOf3 = number / 3;
        if(number - timesOf3*3 == 1)
            --timesOf3;
        int timesOf2 =(number-timesOf3*3) /2;
        return (int)pow(3, timesOf3) * (int)pow(2,timesOf2);
    }
};

猜你喜欢

转载自blog.csdn.net/qq_35353824/article/details/107751117