貪心算法~~

目錄

一、理論基礎

二、題目練習

(1)455. 分發餅干

(2)53. 最大子數組和 - 力扣

(3)122. 買賣股票的最佳時機 II - 力扣(LeetCode)

(4)860. 檸檬水找零 - 力扣(LeetCode)

(5)905. 區間選點 - AcWing題庫

?(6)AcWing 908. 最大不相交區間數量

?(7)906. 區間分組 - AcWing題庫

?(8)907. 區間覆蓋 - AcWing題庫

?(9)148. 合并果子 - AcWing題庫

?(10)913. 排隊打水 - AcWing題庫

(11)104. 貨倉選址 - AcWing題庫

一、理論基礎

貪心的本質是選擇每一階段的局部最優,從而達到全局最優

????????例如,有一堆鈔票,你可以拿走十張,如果想達到最大的金額,你要怎么拿?

指定每次拿最大的,最終結果就是拿走最大數額的錢。

每次拿最大的就是局部最優,最后拿走最大數額的錢就是推出全局最優。

????????再舉一個例子如果是 有一堆盒子,你有一個背包體積為n,如何把背包盡可能裝滿,如果還每次選最大的盒子,就不行了。這時候就需要動態規劃


> 什么時候用貪心?

? ? ? ? hhh卡哥說沒有具體場景,,手動模擬一下感覺可以局部最優推出整體最優,而且想不到反例,那么就試一試貪心。貪心有時候就是常識性的推導,所以會認為本應該就這么做!

> 一般解題步驟?

  • 將問題分解為若干個子問題
  • 找出適合的貪心策略
  • 求解每一個子問題的最優解
  • 將局部最優解堆疊成全局最優解

確實過于理論化。。。。~一般都會涉及到排序 、找規律、反證其可行性

?我們直接練題!!!

二、題目練習

(1)455. 分發餅干

????????局部最優就是大餅干喂給胃口大的,充分利用餅干尺寸喂飽一個,全局最優就是喂飽盡可能多的小孩

最終代碼:

class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s) {//給孩子和餅干排序sort(g.begin(),g.end());sort(s.begin(),s.end());int res=0;int index=s.size()-1;//將大餅干優先分給胃口大的孩子for(int i=g.size()-1;i>=0;i--)//遍歷胃口{if(index>=0&&s[index]>=g[i]) //遍歷餅干 {index--; //可以分配就指向下一個更大的餅干 res++;}}return res;}
};

?感覺還挺簡單的,難在找到他的局部最優性質

(2)53. 最大子數組和 - 力扣

解法一: 可以暴力,但是時間復雜度會高

?解法二:dp,之前我們有做過~

解法三:貪心

????????如果 -2 1 在一起,計算起點的時候,一定是從 1 開始計算,因為負數只會拉低總和,這就是貪心貪的地方!局部最優:當前“連續和”為負數的時候立刻放棄,從下一個元素重新計算“連續和”,因為負數加上下一個元素 “連續和”只會越來越小。

遍歷 nums,從頭開始用 count 累積,如果 count 一旦加上 nums[i]變為負數,那么就應該從 nums[i+1]開始從 0 累積 count 了,因為已經變為負數的 count,只會拖累總和。

?

class Solution {
public:int maxSubArray(vector<int>& nums) {int res=INT_MIN; //一個很小的負數int cnt=0;for(int i=0;i<nums.size();i++){cnt+=nums[i];if(cnt>res)res=cnt;if(cnt<=0) cnt=0; //加上之后非正了,cnt=0相當于重置最大子序起始位置}return res;}
};

(3)122. 買賣股票的最佳時機 II - 力扣(LeetCode)

在dp中我們也做過這道題~~,找到局部最優性質后,用貪心更簡單一點?

局部最優:收集每天的正利潤,全局最優:求得最大利潤

是不是特別簡單哈哈哈

class Solution {
public:int maxProfit(vector<int>& prices) {int result = 0;for (int i = 1; i < prices.size(); i++) {result += max(prices[i] - prices[i - 1], 0);}return result;}
};

(4)860. 檸檬水找零 - 力扣(LeetCode)

?

只需要維護三種金額的數量,5,10和20。

  • 情況一:賬單是5,直接收下。
  • 情況二:賬單是10,消耗一個5,增加一個10
  • 情況三:賬單是20,優先消耗一個10和一個5,如果不夠,再消耗三個5

賬單是20的情況,為什么要優先消耗一個10和一個5呢?

????????因為美元10只能給賬單20找零,而美元5可以給賬單10和賬單20找零,美元5更萬能!

所以局部最優:遇到賬單20,優先消耗美元10,完成本次找零。全局最優:完成全部賬單的找零。

class Solution {
public:bool lemonadeChange(vector<int>& bills) {int five = 0, ten = 0, twenty = 0;for (int bill : bills) {// 情況一if (bill == 5) five++;// 情況二if (bill == 10) {if (five <= 0) return false; //找不了ten++;five--;}// 情況三if (bill == 20) {// 優先消耗10美元,因為5美元的找零用處更大,能多留著就多留著if (five > 0 && ten > 0) {five--;ten--;twenty++; // 其實這行代碼可以刪了,因為記錄20已經沒有意義了,不會用20來找零} else if (five >= 3) {five -= 3;twenty++; // 同理,這行代碼也可以刪了} else return false;}}return true;}
};

?

(5)905. 區間選點 - AcWing題庫

?

?數軸上有一些區間,在數軸上選取幾個點,要求每個區間上最少有一個點。

?????

? ? ? ??

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
struct Range
{int l, r; //左右結點bool operator< (const Range &W)const{return r < W.r; //按照右端點從小到大排序}
}range[N];int main()
{scanf("%d", &n);for (int i = 0; i < n; i ++ ) cin>>range[i].l>>range[i].r;sort(range, range + n);int res = 0, ed = -2e9;for (int i = 0; i < n; i ++ )if (ed < range[i].l) //新的左端點不能覆蓋右端點{res ++ ; //需要新增一個結點ed = range[i].r; //更新右端點}cout<<res;return 0;
}

?(6)AcWing 908. 最大不相交區間數量

?與上一道區間選點的題一樣,一定要是對右端點從小到大排序!!!!

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
struct Range
{int l, r; //左右結點bool operator< (const Range &W)const{return r < W.r; //按照右端點從小到大排序}
}range[N];int main()
{scanf("%d", &n);for (int i = 0; i < n; i ++ ) cin>>range[i].l>>range[i].r;sort(range, range + n);int res = 0, ed = -2e9;for (int i = 0; i < n; i ++ )if (ed < range[i].l) //新的左端點不能覆蓋右端點{res ++ ; //需要新增一個結點ed = range[i].r; //更新右端點}cout<<res;return 0;
}

?(7)906. 區間分組 - AcWing題庫

?等效于把盡可能多的區間塞進同一組,要滿足range[i].l > heap.top

  1. 把所有區間按照左端點從小到大排序
  2. 從前往后枚舉每個區間,判斷此區間能否將其放到現有的組中
  3. heap有多少區間,就有多少組
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
struct Range
{int l, r;bool operator< (const Range &W)const{return l < W.l; //按照左端點排序!!!!}
}range[N];int main()
{cin>>n;for (int i = 0; i < n; i ++ ){int l, r;cin>>l>>r;range[i] = {l, r};}sort(range, range + n);//小根堆(每次彈出最小的數)--每個組的右端點存儲在 heap 中priority_queue<int, vector<int>, greater<int>> heap;for (int i = 0; i < n; i ++ ){//新區間的左端點大于等于堆頂的右端點if (heap.empty() || heap.top() >= range[i].l){heap.push(range[i].r); //開一個新組,記錄其右端點}else { //可以合并heap.pop();//取出右端點最小的區間heap.push(range[i].r);//保留這個右端點較大的區間}}cout<<heap.size();return 0;
}

?(8)907. 區間覆蓋 - AcWing題庫

?

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=1e9+10;
#define PII pair<int ,int>
PII a[N];
int s,t,n;
int main()
{cin>>s>>t;cin>>n;for(int i=0;i<n;i++){cin>>a[i].first>>a[i].second;}sort(a,a+n);int res=0;bool flag=false;//默認無法完全覆蓋for(int i=0;i<n;i++){int j=i,r=-M;while(j<n&&a[j].first<=s){r=max(r,a[j].second);j++;}if(r<s) {res=-1;break;}res++;//最后更新的右端點大于給定區間---能覆蓋if(r>=t) {flag=true;break;}s=r;//每次更新左端點為能覆蓋給定區間的最大的右端點i=j-1;}if(!flag) res=-1;cout<<res;return 0;}

?(9)148. 合并果子 - AcWing題庫

?

在學優先隊列的時候做過這道題~~

priority_queue 優先隊列-CSDN博客

#include<bits/stdc++.h>
using namespace std;
using ll =long long;
ll ans;
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n;cin>>n;priority_queue<ll,vector<ll>,greater<ll>> pq;while(n--){ll x;cin>>x;pq.push(x);}while(pq.size()>=2){ll x=pq.top();pq.pop();ll y=pq.top();pq.pop();ans+=x+y;pq.push(x+y);}cout<<ans;return 0;
}

?(10)913. 排隊打水 - AcWing題庫

需要將打水時間最短的人先打水 --計算前綴和數組的和(不包含最后一個人)

?

#include<bits/stdc++.h>
using namespace std;
using LL=long long;
int main()
{int n;cin>>n;vector<LL> a(n+1);vector<LL> qz(n+1,0);//前綴和數組for(int i=1;i<=n;i++) cin>>a[i];//從小到大排序sort(a.begin(),a.end());//計算排序后的前綴和數組(不用計算最后一個)for(int i=1;i<n;i++) qz[i]=qz[i-1]+a[i];//求前綴和的sumcout<<accumulate(qz.begin()+1,qz.end(),0ll);return 0;
}

(11)104. 貨倉選址 - AcWing題庫

貪心策略:一開始自己也猜到了哈哈哈就是中位數

?排序 +中位數

#include <bits/stdc++.h>
using namespace std;
const int N=100100;
int a[N],n,i,ans,sum;
int main()
{cin>>n;for (i=1;i<=n;i++)cin>>a[i];sort(a+1,a+1+n);//排序int sm=a[n/2+1];//中位數for (i=1;i<=n;i++)ans=ans+abs(a[i]-sm);//統計和中位數之間的差cout<<ans;return 0;
}

?

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

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

相關文章

形象解釋 HTTP 的四種常見請求方式及其中的區別聯系

HTTP 的常見請求方式常見的有四種&#xff1a;GET、POST、PUT、DELETE&#xff0c;它們各自的功能不一樣。 &#x1f35c; 場景比喻&#xff1a;HTTP 請求像“去餐廳點菜” 請求方式行為餐廳比喻說明GET獲取數據看菜單/問服務員&#xff1a;你們有什么菜&#xff1f;不帶食材、…

string的基本使用

string的模擬實現 string的基本用法string的遍歷&#xff08;三種方式&#xff09;&#xff1a;關于auto&#xff08;自動推導&#xff09;:范圍for: 迭代器普通迭代器(可讀可改&#xff09;const迭代器&#xff08;可讀不可改&#xff09; string細小知識點string的常見接口引…

kubernetes》》k8s》》證書有效期

cd /etc/kubernetes/pki openssl x509 -in apiserver.crt -text -noount通常&#xff0c;Kubernetes的證書是由kubeadm生成的&#xff0c;所以可能需要修改kubeadm的源碼或者配置 登錄Master節點 》》》默認延續1年 # 查看證書 檢查證書有效期 # 該命令顯示 /etc/kubernetes…

LangChain LCEL表達式語言簡介

LangChain表達式語言&#xff08;LCEL&#xff09;是專為構建AI應用鏈設計的聲明式編程框架&#xff0c;通過管道符|實現組件無縫銜接&#xff0c;支持流式處理、異步調用等生產級特性。其核心優勢在于零代碼改動實現原型到生產的過渡&#xff0c;同時保持代碼簡潔性和可維護性…

【計算機視覺】CV實踐項目- 基于PaddleSeg的遙感建筑變化檢測全解析:從U-Net 3+原理到工程實踐

基于PaddleSeg的遙感建筑變化檢測全解析&#xff1a;從U-Net 3原理到工程實踐 技術背景與項目意義傳統方法的局限性深度學習的優勢 核心技術與算法原理U-Net 3架構創新全尺度跳躍連接深度監督機制 變化檢測技術路線 實戰指南&#xff1a;從環境搭建到模型部署環境配置數據準備與…

萬字長文 | Apache SeaTunnel 分離集群模式部署 K8s 集群實踐

文章作者&#xff1a;雷寶鑫 整理排版&#xff1a;白鯨開源 曾輝 Apache SeaTunnel官網鏈接: https://seatunnel.apache.org/ Apache SeaTunnel(以下簡稱SeaTunnel&#xff09;是一款新一代高性能、分布式的數據集成同步工具&#xff0c;正受到業界廣泛關注和應用。SeaTunnel支…

深入解析YOLO v1:實時目標檢測的開山之作

目錄 YOLO v1 算法詳解? ?1. 核心思想? ?2. 算法優勢? ?3. 網絡結構&#xff08;Unified Detection&#xff09;?? ?4. 關鍵創新? ?5. 結構示意圖&#xff08;Fig1&#xff09;? Confidence Score 的計算? 類別概率與 Bounding Box 的關系? 后處理&…

信令與流程分析

WebRTC是h5支持的重要特征之一&#xff0c;有了它&#xff0c;不再需要借助音視頻相關的客戶端&#xff0c;直接通過瀏覽器的Web頁面就可以實現音視頻聊天功能。 WebRTC項目是開源的&#xff0c;我們可以借助WebRTC&#xff0c;構建自己的音視頻聊緹娜功能。無論是前端JS的Web…

BIOS主板(非UEFI)安裝fedora42的方法

BIOS主板(非UEFI)安裝fedora42的方法 現實困難&#xff1a;將Fedora-Workstation-Live-42-1.1.x86_64.iso寫入U盤制作成可啟動U盤啟動fedora42&#xff0c;按照向導將fedora42安裝到真機的sda7分區中得到報錯如下內容&#xff1a; /boot/efi 必需的 /boot/efi必須位于格式化為e…

安卓 Compose 相對傳統 View 的優勢

安卓 Compose 相對傳統 View 的優勢 文章目錄 安卓 Compose 相對傳統 View 的優勢1. 引言2. 核心概念&#xff1a;Compose的革新性設計2.1 Jetpack Compose2.2 傳統安卓View系統 3. 開發體驗&#xff1a;Compose大幅提升效率3.1 使用Jetpack Compose構建UI3.2 使用傳統View系統…

SIEMENS PLC 程序 GRAPH 程序解讀 車型入庫

1、程序載圖1 2、程序截圖2 3、程序解釋 這是一個基于西門子 GRAPH 編程的車型 1 入庫順序控制流程圖&#xff0c;通過狀態機結構&#xff08;狀態框 S 與轉移條件 T&#xff09;描述完整工作流程&#xff0c;具體如下&#xff1a; 整體流程概述 初始化&#xff1a;從 S1&am…

VuePress可以做什么?

VuePress 可以做什么 VuePress 是一個基于 Vue.js 的靜態站點生成器,專注于文檔和內容展示。它結合了 Markdown 的簡潔性和 Vue 的靈活性,適合多種場景的開發需求。以下是 VuePress 的主要用途和功能: 1. 技術文檔網站 VuePress 最初是為編寫 Vue.js 官方文檔而設計的,因…

架構-系統可靠性分析與設計

一、可靠性相關基本概念 1. 可靠性與可用性 可靠性&#xff1a;軟件系統在遇到錯誤、意外操作或系統故障時&#xff0c;仍能維持自身功能特性的能力。 舉例&#xff1a;手機銀行APP在用戶誤操作&#xff08;如快速點擊多次轉賬&#xff09;時&#xff0c;仍能正確處理交易并避…

再談String

1、字符串常量池 1.1 創建對象的思考 下面是兩種創建字符串對象的代碼 public static void main1(String[] args) {String s1 "hello";String s2 "hello";System.out.println(s1 s2);//trueString s3 new String("hello");String s4 new …

《深入淺出ProtoBuf:從環境搭建到高效數據序列化》?

ProtoBuf詳解 1、初識ProtoBuf2、安裝ProtoBuf2.1、ProtoBuf在Windows下的安裝2.2、ProtoBuf在Linux下的安裝 3、快速上手——通訊錄V1.03.1、步驟1&#xff1a;創建.proto文件3.2、步驟2&#xff1a;編譯contacts.proto文件&#xff0c;生成C文件3.3、步驟3&#xff1a;序列化…

基于PHP+Uniapp的互聯網醫院源碼:電子處方功能落地方案

隨著“互聯網醫療”政策紅利持續釋放&#xff0c;互聯網醫院已成為推動醫療數字化轉型的重要方向。在這一趨勢下&#xff0c;電子處方功能模塊作為核心環節&#xff0c;不僅直接關系到線上問診閉環的實現&#xff0c;也成為系統開發中技術難度較高、業務邏輯最為復雜的一部分。…

ARM Cortex-M (STM32)如何調試HardFault

目錄 步驟 1: 實現一個有效的 HardFault 處理程序 步驟 2: 復現 HardFault 并使用調試器分析 步驟 3: 解讀故障信息 步驟 4: 定位并修復源代碼 HardFault 是 ARM Cortex-M 處理器中的一種異常。當處理器遇到無法處理的錯誤&#xff0c;或者配置為處理特定類型錯誤&#xff…

基于歸納共形預測的大型視覺-語言模型中預測集的**數據驅動校準**

摘要 本研究通過分離共形預測&#xff08;SCP&#xff09;框架&#xff0c;解決了大型視覺語言模型&#xff08;LVLMs&#xff09;在視覺問答&#xff08;VQA&#xff09;任務中幻覺緩解的關鍵挑戰。雖然LVLMs在多模態推理方面表現出色&#xff0c;但它們的輸出常常表現出具有…

LangChain4j 搭配 Kotlin:以協程、流式交互賦能語言模型開發

Kotlin 支持 | LangChain4j Kotlin 是一種面向 JVM&#xff08;及其他平臺&#xff09;的靜態類型語言&#xff0c;能夠實現簡潔優雅的代碼&#xff0c;并與 Java 庫無縫互操作。 LangChain4j 利用 Kotlin 擴展和類型安全構建器來增強 Java API&#xff0c;為其增添特定于 Ko…

正大模型視角下的市場結構判斷邏輯

正大模型視角下的市場結構判斷邏輯 在多數交易策略中&#xff0c;結構識別往往先于方向判斷。以正大的數據研判風格為例&#xff0c;其核心邏輯是&#xff1a;價格行為不能孤立解讀&#xff0c;必須結合時間與成交效率來判斷當前結構的有效性。 例如&#xff0c;一個上漲過程&…