【算法作業】均分卡牌,購買股票

問題描述

  1. John 有兩個孩子,在 John病逝后,留下了一組價值不一定相同的魔卡, 現在要求你設計一種策略,幫John的經管人將John的這些遺產分給他的兩個孩子,使得他們獲得的遺產差異最小(每張魔卡不能分拆)。

  2. 假設已知某股票連續若干天的股價,并且如何時候你手上只能由一支股票,即如果你要買入就得先將手上股票賣出,設計一個算法來計算你所能獲取的最大利潤。你最多可以完成 k筆交易。也就是說,你最多可以買k 次,賣 k 次。

    輸入:k = 2, prices = [3,2,7,5,1,4]
    輸出:87-2  +  4-1
    

解題思路

T1

這是一個貪心算法問題還是一個動規問題呢?

在思考這道題的時候,我犯了過于經驗主義的錯誤。因為和之前遇見的題目有過類似的,覺得是貪心,所以沒有多去求證,就框框把代碼寫完了,其實貪心并不能得到全局最優解(😁十分感謝看到我博客的同班同學的提醒)

貪心的思路是:

  1. 將所有的魔卡按照價值從大到小排序。
  2. 從價值最高的魔卡開始,依次分配給兩個孩子中當前遺產較少的那個孩子。
  3. 重復步驟2直到所有的魔卡都被分配完畢。

這樣是有問題的,直接舉反例,當 N = 2 時 cards = [5, 3, 2, 2, 2, 2] 貪心求解ans = 2。然而正確的最優解應該為0,兩個孩子分別[5, 3]和[2, 2, 2, 2]

因此,正確解法為動態規劃

動態規劃的思路是:

  1. 求取所有卡牌價值之和sum
  2. 然后轉換成01背包問題,商品的價值和重量都等于卡牌的價值,背包的上限m = sum/2,盡可能的往這個背包里裝商品使其價值最大,即最靠近sum/2。求得此時的最大價值dp[n][sum/2]ans
  3. 最后此問題的解為sum - 2*ans

T2

那么這道題到底是貪心還是動規呢?

我們知道動規有一道經典例題,就是非升子序列,不覺得這題有幾分相似,都是必須從前往后求最優。其實要證明貪心算法不行只要舉個反例就行了。

于是就根據經驗按照動規的思路來思考。考慮使用二維數組dp[i][j],代表當前狀態的最大利潤,i代表當前是第i次買賣,j代表當前是第j天。

對于每個狀態都有買和不買。為什么是買和不買呢,不是還有賣嗎?其實是賺錢和不賺錢這兩種選擇,賺錢是賣與買之間的差值。所以這道題比一般的動態規劃要更復雜些。

對于每一次買賣,必須有買才有賣,先用maxDiff包括因為買股票虧的錢,一開始由于沒有股票,就等于-prices[1]。這個虧的錢也完全不是負數虧的錢,還要包括之前(上一次買賣)因為賺錢累計的成本,這個maxDiff就是代表本次買賣狀態下的累計成本(比較難理解)。所以 m a x D i f f = m a x ( m a x D i f f , d p [ i ? 1 ] [ j ] ? p r i c e s [ j ] ) maxDiff = max(maxDiff, dp[i-1][j] - prices[j]) maxDiff=max(maxDiff,dp[i?1][j]?prices[j])

對于每一天,都有去賺錢和不賺錢。不賺錢利潤等于昨天的利潤,去賺錢的利潤等于累計成本maxDiff加上prices[j],因此 d p [ i ] [ j ] = m a x ( d p [ i ] [ j ? 1 ] , p r i c e s [ j ] + m a x D i f f ) dp[i][j] = max(dp[i][j-1], prices[j] + maxDiff) dp[i][j]=max(dp[i][j?1],prices[j]+maxDiff)

在樣例下,dp運算結果如下所示。

prices327514
dp[1][j]005555
dp[2][j]005558

這個dp[k][n]就是answer。

完整代碼

T1

#include <bits/stdc++.h>
using namespace std;int main() {// 輸入魔卡數量int n;cout << "請輸入魔卡數量:";cin >> n;// 輸入每張魔卡的價值int cards[101],sum=0;cout << "請輸入每張魔卡的價值:" << endl;for (int i = 1; i <= n; ++i) {cin >> cards[i];sum += cards[i];}//    int middle; 
//    if(sum % 2 ==0)
//    	middle = sum/2;
//    else 
//    	middle = sum/2 + 1;
//    cout<<"middle = "<<middle<<endl;int dp[101][1001];memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++)for(int j=cards[i];j<=sum/2;j++)if(cards[i] <= j)// 如果裝的下 dp[i][j] = max(dp[i-1][j],dp[i-1][j-cards[i]] + cards[i]);else dp[i][j] = dp[i-1][j];int ans = dp[n][sum/2];cout<<ans<<endl;for(int i=1;i<=n;i++){for(int j=1;j<=sum/2;j++)cout<<dp[i][j]<<" ";cout<<endl;}cout<<"ans = "<<sum-2*ans;return 0;
}/* sample input
8 
2 5 6 7 1 7 4 36
5 3 2 2 2 2 
*/

輸出結果

請輸入魔卡數量:8
請輸入每張魔卡的價值:
2 5 6 7 1 7 4 3
17
0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
0 0 0 0 5 5 7 7 7 7 7 7 7 7 7 7 7
0 0 0 0 0 6 7 7 7 7 11 11 13 13 13 13 13
0 0 0 0 0 0 7 7 7 7 11 11 13 14 14 14 14
1 1 1 1 1 1 7 8 8 8 11 12 13 14 15 15 15
0 0 0 0 0 0 7 8 8 8 11 12 13 14 15 15 15
0 0 0 4 4 4 7 8 8 8 11 12 13 14 15 16 17
0 0 3 4 4 4 7 8 8 10 11 12 13 14 15 16 17
ans = 1
請輸入每張魔卡的價值:
5 3 2 2 2 2
8
0 0 0 0 5 5 5 5
0 0 3 3 5 5 5 8
0 2 3 3 5 5 7 8
0 2 3 4 5 5 7 8
0 2 3 4 5 6 7 8
0 2 3 4 5 6 7 8
ans = 0

T2

#include<bits/stdc++.h>
using namespace std;
int main(){int n,k,prices[100],dp[101][101]; // 動態規劃數組大小修改為dp[101][101]cin>>n>>k;memset(dp,0,sizeof(dp));memset(prices,0,sizeof(prices));for(int i=1;i<=n;i++)cin>>prices[i];for(int i=1;i<=k;i++){int maxDiff = -prices[1]; // 數組prices的下標從1開始for(int j=1;j<=n;j++){ dp[i][j] = max(dp[i][j-1],prices[j] + maxDiff);maxDiff = max(maxDiff, dp[i-1][j] - prices[j]);}}cout<<dp[k][n]<<endl;// 打印dp數組cout<<"|dp|";for(int i=1;i<=n;i++)cout<<i<<"|";cout<<endl;cout<<"|";for(int i=1;i<=n+1;i++)cout<<"-|";cout<<endl;for(int i=1;i<=k;i++){cout<<"|"<<i<<"|";for(int j=1;j<=n;j++)cout<<dp[i][j]<<"|";cout<<"\n";}return 0;
}/* simple input
6 2
3 2 7 5 1 4
*/

輸出結果

6 2
3 2 7 5 1 4
8
|dp|1|2|3|4|5|6|
|-|-|-|-|-|-|-|
|1|0|0|5|5|5|5|
|2|0|0|5|5|5|8|

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/12316.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/12316.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/12316.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

搜索引擎的設計與實現(三)

目錄 5 系統詳細實現 5.1實現環境配置 5.2功能實現 5.2.1 建立索引 5.2.2 文件搜索實現 5.2.3 數據庫的連接配置 5.2.4 數據庫搜索實現 5.2.5 后臺數據編輯實現 前面內容請移步 搜索引擎的設計與實現&#xff08;二&#xff09; 免費源代碼&畢業設計論文 搜索…

git-刪除workspace.xml的跟蹤

問題描述 .gitignore 文件內容如下&#xff1a; .pyc *.pyc user_files/ .vscode/ __pycache__//.idea/misc.xml /.idea/modules.xml /.idea/inspectionProfiles/profiles_settings.xml /.idea/inspectionProfiles/Project_Default.xml /.idea/batrp_webbackend-server-dev.i…

NARUTO 復現記錄

1 環境配置 下載項目&#xff0c;一定要 git 下載全項目&#xff0c;下載完后要檢查third_parities 里面的coslam和neural_slam_eval 文件全不全。 git clone --recursive https://github.com/oppo-us-research/NARUTO.git 環境配置 注意 bash scripts/installation/conda…

番外篇 | 利用PyQt5+YOLOv5來搭建目標檢測系統(附可視化界面+功能介紹+源代碼)

前言:Hello大家好,我是小哥談。PyQt5是一個Python綁定的Qt庫,是用于創建圖形用戶界面(GUI)和其他應用程序組件的工具包。PyQt5提供了許多GUI元素,如按鈕、文本框、標簽等,也提供了許多Qt的功能,如網絡、數據庫、XML等。通過PyQt5可以在Python中使用Qt的豐富功能和強大的工…

克服虧損的負面影響 學學現貨白銀止損的方法

一個多月以前&#xff0c;現貨黃金的上漲還十分強勁&#xff0c;一度還逼近歷史的高位30大關。但是我們看近半個月以來&#xff0c;現貨白銀價格出現了調整。很多在高位買入的投資者都承受了較大的虧損&#xff0c;這時候就凸顯出了現貨白銀止損的作用。如果投資者能夠通過近期…

Git 基礎使用(2) 分支管理

文章目錄 分支概念分支使用查看分支分支創建分支切換分支合并合并沖突分支刪除 分支管理快進模式分支策略內容保存錯誤處理 分支概念 &#xff08;1&#xff09;分支概念 Git分支是指在版本控制系統Git中&#xff0c;用來表示項目的不同工作流程或開發路徑的一個重要概念。通過…

【cmake】Windows 環境下編譯第三方依賴源碼(以編譯Xerces庫為例)

第三方依賴源碼的編譯分為兩種&#xff0c;一種是使用 Configure 腳本編譯&#xff0c;另一種是使用 CMakeLists.txt 編譯。Xerces 3.2.3 的編譯方式是 CMakeLists.txt 腳本編譯。 必要軟件&#xff1a; CMake &#xff08;CMake | Download&#xff09;Visual Studio 2019&a…

前端AJAX講解

目錄 1.AJAX是什么&#xff1f; 2.異步交互和同步交互 3.AJAX常見應用情景和優缺點 4.AJAX的優缺點 5.AJAX發送異步請求&#xff08;四步操作&#xff09; 6.經典案例 1.AJAX是什么&#xff1f; AJAX即“Asynchronous JavaScript and XML”&#xff08;異步的JavaScript與…

指針基礎實踐

文章目錄 1.聲明指針2.初始化指針3.指針地址和大小&#xff0c;值4.指針解引用,修改值5.指針指向堆內存&#xff0c;修改值6.申請堆內存并釋放7.數組釋放8.指針運算9.指針遞增10.指針遞減11.指針常量12.常量指針13.常量指針指向常量 1.聲明指針 2.初始化指針 3.指針地址和大小…

【數據結構】二叉樹(Binary Tree)

文章目錄 一、樹的概念及結構二、二叉樹的概念及結構1.二叉樹的概念2.特殊的二叉樹3.二叉樹的性質 三、二叉樹的存儲順序存儲鏈式存儲 四、二叉樹的實現1.創建二叉樹2.二叉樹的遍歷前序遍歷中序遍歷后序遍歷層序遍歷根據遍歷順序創建二叉樹 3.二叉樹的基本操作1.總結點個數2.二…

ctfshow之_萌新web9至web10

一、訪問在線靶場ctfshow 1、web9 如下圖所示&#xff0c;進入_萌新賽的web9問題&#xff0c;題目提醒flag在config.php中&#xff1a; 如上圖所示&#xff0c;可以get傳參&#xff0c;且傳入的參數需要正則匹配system、exec、highlight&#xff0c;且不區分大小寫&#xff0…

C++設計模式|創建型 5.原型模式

1.什么是原型模式&#xff1f; 原型模式?種創建型設計模式&#xff0c;該模式的核?思想是基于現有的對象創建新的對象&#xff0c;?不是從頭開始創建。 在原型模式中&#xff0c;通常有?個原型對象&#xff0c;它被?作創建新對象的模板。新對象通過復制原型對象的屬性和狀…

Mac IDEA 自動補全mybatis sql語句

導航 Mac IDEA 自動補全mybatis sql語句一、點擊IDEA 右側Database選項二、選擇添加對應數據庫三、輸入數據庫信息和方案四、輸入數據庫信息和方案五、成功 Mac IDEA 自動補全mybatis sql語句 背景&#xff1a; 想在Mapper中&#xff0c;能夠實現自動檢索數據庫表和對應的字段…

QT日志類SimpleQtLogger的簡單記錄

在現代軟件開發中&#xff0c;日志記錄是必不可少的部分。它不僅幫助開發者在調試和維護軟件時了解程序的運行狀態&#xff0c;還能提供關鍵的錯誤信息。對于使用Qt框架開發應用程序的開發者來說&#xff0c;選擇一個合適的日志庫至關重要。本文將詳細介紹Qt日志庫SimpleQtLogg…

web前端之sass中的顏色函數、active按鈕激活、hover鼠標懸浮、disabled禁用、scss循環、css

MENU 效果圖htmlsassscss編譯后的css頁面css 效果圖 注意查看藍色按鈕。 html <div class"box"><button class"btn type_1">按鈕</button><button class"btn type_2">按鈕</button><button class"btn ty…

一文讀懂通用漏洞評分系統CVSS4.0:順帶理清CVE、CWE及其與CVSS之間的關系

事件響應和安全團隊論壇 (FIRST&#xff0c;Forum of Incident Response and Security Teams) 于 2023 年 11 月 1 日正式推出第四版通用漏洞評分系統 (CVSS 4.0&#xff0c;Common Vulnerability Scoring System version 4.0)。CVSS 4.0 是評估計算機系統安全漏洞嚴重性的行業…

C++ 多態性

一 多態性的分類 編譯時的多態 函數重載 運算符重載 運行時的多態 虛函數 1 運算符重載的引入 使用C編寫程序時&#xff0c;我們不僅要使用基本數據類型&#xff0c;還要設計新的數據類型-------類類型。 一般情況下&#xff0c;基本數據類型的運算都是運算符來表達&#x…

【C++】詳解C++的模板

目錄 概念 ?編輯 語法 函數模板 類模板 非類型模板參數 模板的特化 函數模板特化 類模板特化 全特化 偏特化 分離編譯 概念 模板是C中非常厲害的設計&#xff0c;模板把通用的邏輯剝離出來&#xff0c;讓不同的數據類型可以復用同一種模板的邏輯&#xff0c;甚至可以…

Flutter 中的 DataTable 小部件:全面指南

Flutter 中的 DataTable 小部件&#xff1a;全面指南 在Flutter的Material組件庫中&#xff0c;DataTable是一個用于展示數據的表格組件&#xff0c;它允許開發者以一種結構化和可滾動的方式展示數據集。DataTable非常適合展示詳細信息&#xff0c;如表格數據、統計數據或配置…

PHP黑魔法之md5繞過

php本身是一種弱語言,這個特性決定了它的兩個特點: 輸入的參數都是當作字符串處理變量類型不需要聲明,大部分時候都是通過函數進行類型轉化php中的判斷有兩種: 松散比較:只需要值相同即可,類型不必相同,不通類型比較會先轉化為同類型,比如全數字字符串和數字比較,會比…