最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言動態(tài)規(guī)劃點殺dp算法LeetCode炒股習題案例解析

 更新時間:2022年02月14日 14:16:25   作者:喬喬家的龍龍  
這篇文章主要介紹為了C語言動態(tài)規(guī)劃點殺dp算法,本文以LeetCode炒股習題案例來為大家進行詳細解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助

概念

說到動態(tài)規(guī)劃,什么是動態(tài)規(guī)劃?

動態(tài)規(guī)劃(英語:Dynamic programming,簡稱 dp)通過把原問題分解為相對簡單的子問題的方式求解復(fù)雜問題的方法。動態(tài)規(guī)劃常常適用于有重疊子問題和最優(yōu)子結(jié)構(gòu)性質(zhì)的問題。

看著這么復(fù)雜哈,其實總結(jié)出來就是大事化小,拆分成小問題但是這些小問題和原問題是同質(zhì)的,動規(guī)致力于解決每一個子問題,減少計算,其實和遞歸思想,分治法有些類似,斐波那契數(shù)列就可以看做入門級的經(jīng)典動規(guī)問題

這里引用一個網(wǎng)上流行的例子來給大家體會一下:

A :“1+1+1+1+1+1+1+1 =?”
A :“上面等式的值是多少”
B :計算 “8”
A : 在上面等式的左邊寫上 “1+” 呢?
A : “此時等式的值為多少”
B : 很快得出答案 “9”
A : “你怎么這么快就知道答案了”
A : “只要在8的基礎(chǔ)上加1就行了”
A : “所以你不用重新計算,因為你記住了第一個等式的值為8!動態(tài)規(guī)劃算法也可以說是 ‘記住求過的解來節(jié)省時間’”

性質(zhì)

1.最優(yōu)化原理:如果問題的最優(yōu)解所包含的子問題的解也是最優(yōu)的,就稱該問題具有最優(yōu)子結(jié)構(gòu),即滿足最優(yōu)化原理(說人話就是切大瓜,切到最小又不影響我體驗)

2.有重疊子問題:即子問題之間是不獨立的,一個子問題在下一階段決策中可能被多次使用到(說人話就是藕斷絲連,拿一個可能帶動其他)

3.無后效性:即某階段狀態(tài)一旦確定,就不受這個狀態(tài)以后決策的影響。也就是說,某狀態(tài)以后的過程不會影響以前的狀態(tài),只與當前狀態(tài)有關(guān)(說人話就是把水化成冰,但本質(zhì)上依然是水)

典型特征

動態(tài)規(guī)劃有4個典型特征:

1.最優(yōu)子結(jié)構(gòu)

2.狀態(tài)轉(zhuǎn)移方程

3.邊界

4.重疊子問題

以我們熟悉的斐波那契數(shù)列為例

在這里插入圖片描述

f(n-1)和f(n-2) 稱為 f(n) 的最優(yōu)子結(jié)構(gòu),f(n)= f(n-1)+f(n-2)就稱為狀態(tài)轉(zhuǎn)移方程,f(1) = 1, f(2) = 2 稱為邊界,其中f(5)= f(4)+f(3),f(4) = f(3) + f(2) ,f(3)就是重疊子問題。

實戰(zhàn)論證

要學(xué)習dp算法就一定得談?wù)?LeetCode 里面的鼻祖題——炒股系列問題,我們就拿例題來港港怎么理解他的典型特征

初始題比較簡單,我們以 II 為例:

在這里插入圖片描述

示例:
輸入: prices = [7,1,5,3,6,4]
輸出: 7

小捷徑

看到這里其實最簡單的方法已經(jīng)明了了,那就是貪心算法,只要能賺,只要不賠我就買買買!你說我貪不貪心?

int maxProfit(int* prices, int pricesSize) {
    int sum = 0;
    for (int i = 1; i < pricesSize; ++i) {
        sum += fmax(0, prices[i] - prices[i - 1]);
    }
    return sum;
}

這里用了一個庫函數(shù) fmax ,需要引頭文件<math.h>,用于比較兩個參數(shù)的最大值,語法是:

type fmax  (參數(shù)1 , 參數(shù)2);

再介紹一種我自己用的方法,和貪心原理上差不多,只是用的普普通通的遍歷:

int maxProfit(int* prices, int pricesSize) {
	int n = 0;
	if (pricesSize == 0)
	{
		return 0;
	}
	int sum = 0;
	while (n < pricesSize - 1)
	{
		for (n = 0; n < pricesSize - 1; n++)
			if (prices[n + 1] - prices[n] > 0)//保證買賣能賺就入手
			{
				sum += prices[n+1]-prices[n];
			}
	}
	return sum;
}

我自己的方法還是比較優(yōu)的

在這里插入圖片描述


這樣就能一套帶走,但我們要用 dp 去搞定他,dp 其實也很簡單,只是看著有點復(fù)雜,咱不能望而卻步是吧。

分析條件,題目中說不能多次買賣,那我們有且只有兩種狀態(tài)就是沒有和有一支,沒有就是手里為0,又有兩種可能就是前一天就是 0 和這一天有一支但被賣出去了;同理,有一支的情況就是前一天就有一支和前一天兩手空空但我今天買進了一支。以此我們寫出求最大利潤的狀態(tài)轉(zhuǎn)移方程( i 從 0 開始):

第i天有0支股票:dp[i][0] = dp[i-1][0] + dp[i][1]+prices[i];
第i天有1支股票:dp[i][1] = dp[i-1][1] + dp[i-1][0]-prices[i];

狀態(tài)轉(zhuǎn)移方程寫出來了,題目就迎刃而解了

算法實現(xiàn)

1、借助數(shù)組或者二維數(shù)組,保存每一個子問題的結(jié)果,具體創(chuàng)建數(shù)組還是二維數(shù)組看題目而定,比如找零錢問題中的不同面值零錢與總錢數(shù),這樣就需要創(chuàng)建一個二維數(shù)組

2、對應(yīng)題干條件,具體要求來設(shè)置數(shù)組邊界值,一維數(shù)組就是設(shè)置第一個數(shù)字,二維數(shù)組就是設(shè)置第一行跟第一列的值

3、找出狀態(tài)轉(zhuǎn)換方程,找到每個狀態(tài)跟他上一個狀態(tài)的關(guān)系,根據(jù)狀態(tài)轉(zhuǎn)化方程就可以寫出代碼

我們用剛剛推出來的狀態(tài)轉(zhuǎn)移方程就可以寫出整個代碼框架:

int maxProfit(int* prices, int pricesSize) {
    int sz = pricesSize;
    int i = 0;
    int dp[sz][2] = 0; //sz是最大買賣天數(shù)內(nèi)的價格,2代表兩種狀態(tài)0和1
    dp[0][0] = 0,dp[0][1]=-prices[0];//設(shè)置邊界值
    for(i=0;i<sz;i++)
    {
    dp[i][0] = fmax(dp[i-1][0] + dp[i][1]+prices[i]);
    dp[i][1] = fmax(dp[i-1][1] + dp[i-1][0]-prices[i]);//兩種狀態(tài)分別求最大利潤
    }
    return [sz-1][0];
  }

優(yōu)化

我們不難發(fā)現(xiàn),我們的收益只和股票前一天的價格掛鉤,和更早的狀態(tài)沒有關(guān)系,那我們?yōu)榱藴p小時間復(fù)雜度和空間復(fù)雜度,可以將二維數(shù)組轉(zhuǎn)化成一維滾動數(shù)組搞定

int maxProfit(int* prices, int pricesSize) {
    int dp[pricesSize][2];
    int dp0 = 0;dp1 = -prices[0];
    for (int i = 1; i < pricesSize; ++i)
     {
       int Dp0 = fmax(dp0, dp1+prices[i]);
        Dp1 = fmax(dp1, dp0-prices[i]); //同理轉(zhuǎn)換出狀態(tài)轉(zhuǎn)移方程
    }
    dp0 = Dp0;
    dp1 = Dp1;//滾動更新dp0和dp1
    return dp[pricesSize - 1][0];
}

好了,今天就先到這里,摸了家人們,更多關(guān)于C語言動態(tài)規(guī)劃點殺dp算法的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入理解strcpy與memcpy的區(qū)別

    深入理解strcpy與memcpy的區(qū)別

    本篇文章是對strcpy與memcpy的區(qū)別進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 利用C語言實現(xiàn)將格式化數(shù)據(jù)和字符串相互轉(zhuǎn)換

    利用C語言實現(xiàn)將格式化數(shù)據(jù)和字符串相互轉(zhuǎn)換

    這篇文章主要為大家詳細介紹了2個函數(shù),分別是sprintf和sscanf,可以用來實現(xiàn)將格式化數(shù)據(jù)和字符串相互轉(zhuǎn)換,感興趣的小伙伴可以跟隨小編一起學(xué)習一下
    2023-03-03
  • C語言實現(xiàn)個人通訊錄管理系統(tǒng)

    C語言實現(xiàn)個人通訊錄管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)個人通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C++11中l(wèi)ambda、std::function和std:bind詳解

    C++11中l(wèi)ambda、std::function和std:bind詳解

    大家都知道C++11中增加了許多的新特性,下面在這篇文中我們就來聊一下lambda表達式,閉包,std::function以及std::bind。文中介紹的很詳細,相信對大家具有一定的參考價值,有需要的朋友們下面來一起看看吧。
    2017-01-01
  • C 語言基礎(chǔ)之C語言的常見關(guān)鍵字

    C 語言基礎(chǔ)之C語言的常見關(guān)鍵字

    C語言中有一些預(yù)先定義的字符串,他們本身被賦予了自身的功能。并且我們在定義變量的時候,不能去搶他們的名字來用。他們就是今天的主角:關(guān)鍵字,下面文章將給大家做詳細介紹
    2021-09-09
  • C++基于棧的深搜算法實現(xiàn)馬踏棋盤

    C++基于棧的深搜算法實現(xiàn)馬踏棋盤

    這篇文章主要為大家詳細介紹了C++基于棧的深搜算法實現(xiàn)馬踏棋盤,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C++ Qt實現(xiàn)瀏覽器網(wǎng)頁內(nèi)嵌的音視頻播放器

    C++ Qt實現(xiàn)瀏覽器網(wǎng)頁內(nèi)嵌的音視頻播放器

    這篇文章主要為大家詳細介紹了如何利用C++ Qt實現(xiàn)瀏覽器網(wǎng)頁內(nèi)嵌的音視頻播放器,并支持軟硬解碼,支持音頻,支持錄像截圖,支持多路播放等,感興趣的可以了解下
    2024-01-01
  • C語言中#define在多行宏定義出錯的原因及分析

    C語言中#define在多行宏定義出錯的原因及分析

    這篇文章主要介紹了C語言中#define在多行宏定義出錯的原因及分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C++常用的11種設(shè)計模式解釋及示例代碼詳解

    C++常用的11種設(shè)計模式解釋及示例代碼詳解

    c++常用的設(shè)計模式包括單例模式、工廠模式、抽象工廠模式、適配器模式、裝飾者模式、代理模式、外觀模式、橋接模式、組合模式、享元模式、觀察者模式和命令模式等,這篇文章主要介紹了C++常用的11種設(shè)計模式解釋及示例,需要的朋友可以參考下
    2023-02-02
  • C++實現(xiàn)學(xué)生管理系統(tǒng)

    C++實現(xiàn)學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07

最新評論

柏乡县| 弋阳县| 五华县| 乐业县| 米脂县| 延吉市| 诸城市| 青州市| 颍上县| 新巴尔虎左旗| 三河市| 东安县| 科尔| 扶风县| 津南区| 庄浪县| 东源县| 甘洛县| 长垣县| 伊金霍洛旗| 明光市| 深水埗区| 九龙县| 靖安县| 轮台县| 县级市| 册亨县| 金门县| 朝阳县| 哈密市| 邵东县| 诏安县| 宕昌县| 寻乌县| 盐津县| 东海县| 东乡族自治县| 安顺市| 清徐县| 西华县| 杭锦后旗|