【刷题篇】动态规划(五)

文章目录

  • 1、删除并获得点数
  • 2、粉刷房子
  • 3、买卖股票的最佳时机含冷冻期
  • 4、买卖股票的最佳时机含手续费
  • 5、买卖股票的最佳时机 III
  • 6、买卖股票的最佳时机 IV

1、删除并获得点数

给你一个整数数组 nums ,你可以对它进行一些操作。
每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素。
开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数
【刷题篇】动态规划(五)_第1张图片

class Solution {
public:
    int deleteAndEarn(vector<int>& nums) {
        //初始化
        const int N=10001;
        int arr[N]={0};
        for(auto x:nums)
            arr[x]+=x;
        //填表
        vector<int> d(N);
        auto p =d;
        d[0]=arr[0];
        for(int i=1;i<N;i++)
        {
            d[i]=p[i-1]+arr[i];
            p[i]=max(d[i-1],p[i-1]);
        }
        return max(d[N-1],p[N-1]);
    }
};

2、粉刷房子

假如有一排房子,共 n 个,每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。
当然,因为市场上不同颜色油漆的价格不同,所以房子粉刷成不同颜色的花费成本也是不同的。每个房子粉刷成不同颜色的花费是以一个 n x 3 的正整数矩阵 costs 来表示的。
例如,costs[0][0] 表示第 0 号房子粉刷成红色的成本花费;costs[1][2] 表示第 1 号房子粉刷成绿色的花费,以此类推。
请计算出粉刷完所有房子最少的花费成本。

【刷题篇】动态规划(五)_第2张图片

class Solution {
public:
    int minCost(vector<vector<int>>& costs) {
        //创建dp
        int row=costs.size();
        vector<vector<int>> dp(row+1,vector<int>(3));
        //填表
        for(int i=1;i<row+1;i++)
        {
            dp[i][0]=min(dp[i-1][1],dp[i-1][2])+costs[i-1][0];
            dp[i][1]=min(dp[i-1][0],dp[i-1][2])+costs[i-1][1];
            dp[i][2]=min(dp[i-1][0],dp[i-1][1])+costs[i-1][2];
        }
        return min(dp[row][0],min(dp[row][1],dp[row][2]));
    }
};

3、买卖股票的最佳时机含冷冻期

给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。​
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

【刷题篇】动态规划(五)_第3张图片

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //分为三个状态,买入=0,可交易=1,冷冻期=2
        //创建dp
        int n=prices.size();
        vector<vector<int>> dp(n,vector<int>(3));
        //初始化
        dp[0][0]=-prices[0];
        //填表
        for(int i=1;i<n;i++)
        {
            dp[i][0]=max(dp[i-1][1]-prices[i],dp[i-1][0]);//买入
            dp[i][1]=max(dp[i-1][2],dp[i-1][1]);
            dp[i][2]=dp[i-1][0]+prices[i];
        }
                    //处于买入状态是可以不用比较的
        return max(dp[n-1][0],max(dp[n-1][1],dp[n-1][2]));
    }
};

4、买卖股票的最佳时机含手续费

给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。
你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。
返回获得利润的最大值。
注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。
【刷题篇】动态规划(五)_第4张图片

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        int size=prices.size();
        vector<int> d(size);//买入
        auto p=d;//空
        d[0]=-prices[0];
        p[0]=0;

        for(int i=1;i<size;i++)
        {
            d[i]=max(d[i-1],p[i-1]-prices[i]);
            p[i]=max(d[i-1]+prices[i]-fee,p[i-1]);
        }
        return max(d[size-1],p[size-1]);//其实只需要返回p表的就可以了
    }
};

5、买卖股票的最佳时机 III

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)
【刷题篇】动态规划(五)_第5张图片

class Solution {
public://INT_MIN/INT_MAX会出现边界问题,所以以后就用最大值或者最小值的一半0X3F3F3F3F/-0X3F3F3F3F
    int maxProfit(vector<int>& prices) {
        int n=prices.size();
        vector<vector<int>> d(n,vector<int>(3,-0X3F3F3F3F));
        auto p=d;

        d[0][0]=-prices[0];
        p[0][0]=0;

        for(int i=1;i<n;i++)
        {
            for(int j=0;j<3;j++)
            {
                d[i][j]=max(d[i-1][j],p[i-1][j]-prices[i]);
                p[i][j]=p[i-1][j];
                
                if(j>=1)
                    p[i][j]=max(p[i][j],d[i-1][j-1]+prices[i]);
            }
        }

        int maxi=0;
        for(int i=0;i<3;i++)
            maxi=max(maxi,p[n-1][i]);
        return maxi;
    }
};

6、买卖股票的最佳时机 IV

给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

【刷题篇】动态规划(五)_第6张图片

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n=prices.size();
        vector<vector<int>> d(n,vector<int>(k+1,-0X3F3F3F3F));
        auto p=d;
        d[0][0]=-prices[0];
        p[0][0]=0;
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<=k;j++)
            {
                d[i][j]=max(d[i-1][j],p[i-1][j]-prices[i]);
                p[i][j]=p[i-1][j];
                if(j>=1)
                {
                    p[i][j]=max(p[i][j],d[i-1][j-1]+prices[i]);
                }
            }
        }
        int maxi=0;
        for(int i=0;i<=k;i++)
        {
            maxi=max(p[n-1][i],maxi);
        }
        return maxi;
    }
};

你可能感兴趣的:(刷题篇,动态规划,算法)