文章目录
- 1、删除并获得点数
- 2、粉刷房子
- 3、买卖股票的最佳时机含冷冻期
- 4、买卖股票的最佳时机含手续费
- 5、买卖股票的最佳时机 III
- 6、买卖股票的最佳时机 IV
给你一个整数数组 nums ,你可以对它进行一些操作。
每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素。
开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数
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]);
}
};
假如有一排房子,共 n 个,每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。
当然,因为市场上不同颜色油漆的价格不同,所以房子粉刷成不同颜色的花费成本也是不同的。每个房子粉刷成不同颜色的花费是以一个 n x 3 的正整数矩阵 costs 来表示的。
例如,costs[0][0] 表示第 0 号房子粉刷成红色的成本花费;costs[1][2] 表示第 1 号房子粉刷成绿色的花费,以此类推。
请计算出粉刷完所有房子最少的花费成本。
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]));
}
};
给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
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]));
}
};
给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。
你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。
返回获得利润的最大值。
注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。
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表的就可以了
}
};
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)
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;
}
};
给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
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;
}
};