leecode 解题总结:123. Best Time to Buy and Sell Stock III

来源:互联网 发布:公司礼品 知乎 编辑:程序博客网 时间:2024/05/20 02:22
#include <iostream>#include <stdio.h>#include <vector>using namespace std;/*问题:Say you have an array for which the ith element is the price of a given stock on day i.Design an algorithm to find the maximum profit. You may complete at most two transactions.Note:You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).分析:至少要交易两次,求取至少交易两次下的最大值。因为无法确定到底交易多少次。也有可能一直在亏损,那么就要选取亏损较少的时候。这个有点类似于广度优先搜索求解最优,但这个是如果是暴力破解:没办法破解,因为至少两次,至多只有n-1次,应该是一个动态规划问题。设dp[i]表示截止到天数i获得的最大利润。B[i]表示最近一次抛售股票的日期,那么dp[i+1]要么是还等于dp[i],记j=B[i],从j到天数i+1中选择出一个两天,组成一次交易并且有maxNum = 0;maxNum = max( A[i+1] - A[j] , maxNum ),其中j 属于[ B[i] , i ]如果maxNum > 0,那么又选择了j和i+1作为一次新的交易设计一个计数器cunt,每次组成新的交易,累加,目标是dp[n],先计算第一遍,求出dp[n],如果count = 0,说明没有选择交易,说明整个是降序的,那么遍历一遍,选择两次:两个差值最大的(实际比如9 7,和9 4,两个查实分别为-2,-5,应该选择-2)如果count = 1,说明还缺少一次交易,则根据之前一次记录的交易截止天数i,从i到n开始都是降序,那么就寻找两个差值最大的如果count >= 2,直接返回结果似乎还是不对。看答案:leecode:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/?tab=Solutions需要维护一个通过k次交易,到达prices[i]时候的最大利润,也就是记录了:交易次数,交易截止日期i,以及最大利润三个变量【关键】我没想到是记录交易次数,但题目说了交易次数,就应该把其抽象为要记录的变量设dp[k][i]表示截止到prices[i],通过k次交易,所能得到的最大利润,不包括第prices[i],八这个变量需要留作下一次使用第k次得到最大利润,等于截止到日期j,通过k-1次得到最大的利润,加上prices[j] - prices[i]的利润 和 不需要包含当前这个元素的利润dp[k-1][i-1]的最大值中的其中一个,漏了dp[k][i]= max(dp[k][i-1], dp[k-1][j] + prices[i] - prices[j] ),其中j属于[]dp[0][i] = 0,表明通过0次想要赚得的最大利润为0dp[k][0]= 0,表明如果仅有一个价格prices[0],那么获得的最大利润为02//dp[0][i] = 0//dp[k][0] = 0,所以无需再初始化//dp[k][i] = max( dp[k][i-1] , dp[k-1][j] + prices[i] - prices[j] ),j属于[0 , i-1]//         = max ( dp[k][i-1], prices[i] + max(dp[k-1][j] - prices[j]),牛逼,把常量全部提取出来//目标值dp[2][n-1]int maxProf = 0;for(int k = 1 ; k <= K ; k++)//这里限定k的结果,必须从1开始因为后面有k-1{int tempMax = dp.at(k-1).at(0) - prices.at(0);for(int i = 1; i < size ; i++)//下标从1开始{dp.at(k).at(i) = max( dp.at(k).at(i-1) , prices.at(i) + tempMax );//牛逼把常量拆分出来,最大值通过一次遍历即可,无需再次开一个循环tempMax = max(tempMax , dp.at(k-1).at(i) - prices.at(i));maxProf = max(maxProf, dp.at(k).at(i));}}*/class Solution {public:    int maxProfit(vector<int>& prices) {        if(prices.empty()){return 0;}//只有1个价格,无法交易if(prices.size() <= 1){return 0;}int size = prices.size();int K = 2;vector< vector<int> > dp( K + 1, vector<int>(size , 0) );//dp[0][i] = 0//dp[k][0] = 0,所以无需再初始化//dp[k][i] = max( dp[k][i-1] , dp[k-1][j] + prices[i] - prices[j] ),j属于[0 , i-1]//         = max ( dp[k][i-1], prices[i] + max(dp[k-1][j] - prices[j]),牛逼,把常量全部提取出来//目标值dp[2][n-1]int maxProf = 0;for(int k = 1 ; k <= K ; k++)//这里限定k的结果,必须从1开始因为后面有k-1{int tempMax = dp.at(k-1).at(0) - prices.at(0);for(int i = 1; i < size ; i++)//下标从1开始{dp.at(k).at(i) = max( dp.at(k).at(i-1) , prices.at(i) + tempMax );//牛逼把常量拆分出来,最大值通过一次遍历即可,无需再次开一个循环tempMax = max(tempMax , dp.at(k-1).at(i) - prices.at(i));maxProf = max(maxProf, dp.at(k).at(i));}}return maxProf;}};void print(vector<int>& result){if(result.empty()){cout << "no result" << endl;return;}int size = result.size();for(int i = 0 ; i < size ; i++){cout << result.at(i) << " " ;}cout << endl;}void process(){ vector<int> nums; int value; int num; Solution solution; vector<int> result; while(cin >> num ) { nums.clear(); for(int i = 0 ; i < num ; i++) { cin >> value; nums.push_back(value); } }}int main(int argc , char* argv[]){process();getchar();return 0;}

0 0
原创粉丝点击