算法-动态规划(一)

14 篇文章 0 订阅

动态规划(一)

  • 动态规划方法通产用来求解最优化问题
    1. 刻画一个最优解的结构特征
    2. 递归地定义最优解得值
    3. 计算最优解得值,通常采用自底向上的方法
    4. 利用计算出的信息构造一个最优解
  • 使用情况:
    1. 具有重叠子问题
    2. 需要记录表

钢条切割

分治法
int cutRod(vector<int> &p,int n){
    if (n==0) return 0;
    int q=INT_MIN;
    for(int i=0;i<n;i++)
        q=max(q,p[i]+cutRod(p,n-i));
    return q;
}
自顶向下的DP
int memoizedCutRod(vector<int> &p,int n){
    vector<int> r(n+1,INT_MIN);
    return memoizedCutRodAux(p,n,r);
}
int memoizedCutRodAux(vector<int> &p,int n,vector<int> &r){
    if(r[n]>=0) return r[n];
    int q;
    if(!n) q=0;
    else {
        q=INT_MIN;
        for(int i=0;i<n;i++)
            q=max(q,p[i]+memoizedCutRodAux(p,n-i,r));
    }
    r[n]=q;
    return q;
}
自底向上DP
int BottomUpCutRod(vector<int> &p,int n){
    vector<int> r(n+1,0);
    for(int j=0;j<n;j++){
        int q=INT_MIN;
        for(int i=0;i<j;i++)
            q=max(q,p[i]+r[j-i]);
        r[j]=q;
    }
    return r[n];
}

最优子结构

最长公共子序列 LCS
int LCS(string A, string B){
    int m=A.length();
    int n=B.lenght();
    vector<vector<int>> c(m,vector<int>(n,0));
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            if(A[i-1]==B[j-1])
                c[i][j]=c[i-1][j-1]+1;
            else
                c[i][j]=max(c[i-1][j],c[i][j-1]);
        }
    }
    return c[m][n];
}
最长递增子序列
int lengthOfLIS(vector<int>& nums){
    int len=nums.size();
    if(len<=1) return len;
    vector<int> r(len,1);
    int longest=1;
    for(int i=1;i<len;i++){
        for(int j=0;j<i;j++){
            if(nums[j]<nums[i])
                r[i]=max(r[i],r[j]+1);
        }
        longest=max(longest,r[i]);
    }
    return longest;
}
最小路径和
int minPathSum(vector<vector<int>>& grid){
    if(grid.empty()||!grid.size()||!grid[0].size())
        return 0;
    int m=grid.size();
    int n=grid[0].size();
    vector<vector<int>>& dp(m,vector<int>(n,0));
    dp[0][0]=grid[0][0];
    for(int i=1;i<m;i++)
        dp[i][0]+=dp[i-1][0]+grid[i][0];
    for(int j=1;j<n;j++)
        dp[0][j]+=dp[0][j-1]+grid[0][j];
    for(int i=1;i<m;i++){
        for(int j=1;j<n;j++){
            dp[i][j]=min(dp[i-1][j], dp[i][j-1])+ grid[i][j];
        }
    }
    return dp[m-1][n-1];
}
最大子数组和
int maxSubArray(vector<int>& nums){
    if(nums.empty()) return 0;
    int len=nums.size();
    int sum=0,maxnum=nums[0];
    for(int i=0;i<len;i++){
        sum+=nums[i];
        maxnum=max(maxnum,sum);
        sum=max(sum,0);
     }
     return maxnum;
}
最大子数组乘积
int maxProduct(vector<int>& nums) {
    if (nums.empty()) return 0;
    int maxEndHere=nums[0],minEndHere=nums[0];
    int maxSoFar = nums[0];

    for (int i=1; i<nums.size(); i++) {
        if (nums[i]<0) swap(maxEndHere,minEndHere);
        maxEndHere=max(maxEndHere*nums[i], nums[i]);
        minEndHere=min(minEndHere*nums[i], nums[i]);
        maxSoFar = max(maxEndHere, maxSoFar);
    }
    return maxSoFar;
}
Maximal Square
int maximalSquare(vector<vector<char>>& matrix){
    int m = matrix.size();
    if (!m) return 0;
    int n = matrix[0].size();
    vector<vector<int> > size(m, vector<int>(n, 0));
    int maxsize = 0;
    for (int j = 0; j < n; j++) {
       size[0][j] = matrix[0][j] - '0';
       maxsize = max(maxsize, size[0][j]);
    }
    for (int i = 1; i < m; i++) {
       size[i][0] = matrix[i][0] - '0';
       maxsize = max(maxsize, size[i][0]);
    }
    for (int i = 1; i < m; i++) {
        for (int j = 1; j < n; j++) {
           if (matrix[i][j] == '1') {
               size[i][j] = min(size[i-1][j-1], min(size[i-1][j], size[i][j-1]))+1;
                maxsize = max(maxsize, size[i][j]);
           }
       }
    }
    return maxsize * maxsize;
}

Best Time to Buy and Sell Stock

Best Time to Buy and Sell StockI
int maxProfit(vector<int>& prices){
    if(prices.size()<=1) return 0;
    int lprice=prices[0];
    int profit=0;
    for(int i=0;i<prices.size();i++){
        profit=max(prices[i]-lprice,profit);
        lprice=min(prices[i],profit);
    }
    return profit;
}
Best Time to Buy and Sell StockII
int maxProfit(vector<int>& prices) {
    int len=prices.size();
    int temp=0;
    for(int i=1;i<len;i++){
        if(prices[i]>prices[i-1])
        temp+=prices[i]-prices[i-1];
    }
    return temp;
}
Best Time to Buy and Sell StockIV
int maxProfit(int k, vector<int>& prices){
    int n=prices.size();
    if (n<=1) return 0;

    if (k>=n/2) {
        int maxPro = 0;
        for (int i=1; i<n; i++) {
            if (prices[i]>prices[i-1])
                maxPro+=prices[i]-prices[i-1];
         }
         return maxPro;
     }

     vector<vector<int>> dp(k+1,vector<int>(n,0));
     for (int i=1; i<=k; i++) {
          int localMax=dp[i-1][0]-prices[0];
          for (int j=1; j<n; j++) {
              dp[i][j]=max(dp[i][j-1],  prices[j]+localMax);
              localMax=max(localMax, dp[i-1][j]-prices[j]);
          }
     }
     return dp[k][n-1];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值