一、英语
二、leetcode
1、714:动态规划 or 贪心
方法一:动态规划
//动态规划
//股票买卖,寻求最大利益,并且同一天价格相同,不考虑同一天买入又卖出的情况
//dp[i][0]表示第i天结束的时候没有股票的最大收益
//dp[i][1]表示第i天结束的时候有股票的最大收益
//递推式子:dp[i][0] = max(dp[i-1][1]+p[i-1]-fee,dp[i-1][0])
//dp[i][1] = max(dp[i-1][0]-p[i-1],dp[i-1][1])
//方法一:动态规划,可以进行空间优化(省略)
int maxProfit(vector<int>& prices, int fee) {
int n = prices.size();
if(n==0)
return 0;
vector<vector<int>> dp(n+1,vector<int>(2,0));
dp[1][0] = 0;
dp[1][1] = -prices[0];
for(int i = 2;i<=n;++i)
{
dp[i][0] = max(dp[i-1][1]+prices[i-1]-fee,dp[i-1][0]);
dp[i][1] = max(dp[i-1][0]-prices[i-1],dp[i-1][1]);
}
return dp[n][0];
}
方法二:贪心
//方法二:贪心,将fee视为买入价格
//buy为当前最小买入价格,只要今日价格大于buy就暂时卖出,遇到更低买入价格时更新buy
int maxProfit(vector<int>& prices, int fee)
{
int n = prices.size();
if(n==0)
return 0;
int buy = prices[0]+fee;
int res = 0;
for(int i = 1;i<n;++i)
{
if((prices[i]+fee)<buy)
buy = prices[i]+fee;
else if(prices[i]>buy)
{
res += prices[i]-buy;
buy = prices[i];
}
}
return res;
}
2、241:动态规划 or 分治
方法一:分治,从上往下
class Solution {
public:
//方法一:分治,从上到下将问题变小
vector<int> diffWaysToCompute(string expression) {
int n = expression.size();
vector<int> res;
if(n==0)
return res;
for(int i = 0;i<n;++i)
{
char c = expression[i];
//只有是符号的时候才进行划分左右
if(c=='+'||c=='-'||c=='*')
{
vector<int> left = diffWaysToCompute(expression.substr(0,i));
vector<int> right = diffWaysToCompute(expression.substr(i+1));
//left和right返回的就是左边和右边所有可能的组合结果
//这里根据符号的情况要遍历所有的结果
for(auto x:left)
for(auto y:right)
{
if(c=='+')
res.push_back(x+y);
else if(c=='-')
res.push_back(x-y);
else
res.push_back(x*y);
}}
}
//base case,最小问题
if(res.empty())
res.push_back(stoi(expression));
return res;
}
};
方法二:分治有很多重复计算=》从下网上的动态规划
//方法二:动态规划
//首先要分别得到数字和符号
//dp[i][j]表示数字i到j所有可能结果
//递推式子:以op[k]作为符号,遍历dp[i][k]和dp[k+1][j]的所有可能结果
//计算[i,j]的时候需要用到更小的[i,k]和[k,j],所以当j确定,i应该从接近j的位置开始,也就是j-1
vector<int> diffWaysToCompute(string expression)
{
//首先分别得到数字和符号
vector<int> nums;
vector<int> ops;
int n = expression.size();
int num = 0;
for(int i = 0;i<n;++i)
{
if(expression[i]<'0'||expression[i]>'9')
{
nums.push_back(num);
num = 0;
ops.push_back(expression[i]);
}
else
{
num = num*10+(expression[i]-'0');
}
}
//还有最后一个数字
nums.push_back(num);
n = nums.size();
//dp[i][j]是一个vector,因为可能有多种结果
vector<vector<vector<int>>> dp(n+1,vector<vector<int>>(n+1));
//首先确定j
//初始条件
for(int i = 1;i<=n;++i)
dp[i][i].push_back(nums[i-1]);
for(int j = 2;j<=n;++j)
for(int i = j-1;i>=1;--i)//i从后往前
for(int k = i;k<j;++k)//k从i开始取,不然都用不到dp[i][i]
{
for(auto x:dp[i][k])
for(auto y:dp[k+1][j])
{
if(ops[k-1]=='+')
dp[i][j].push_back(x+y);
else if(ops[k-1]=='-')
dp[i][j].push_back(x-y);
else
dp[i][j].push_back(x*y);
}
}
return dp[1][n];
}
今日份动力