2021-4-21

一、英语

二、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];
    }

今日份动力
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值