一道很簡單的貪心算法題~【貪心:我不要臉的伐?】

文章目錄

  • 題目描述
  • 輸入
  • 輸出
  • 樣例輸入
  • 樣例輸出
  • C語言代碼實現
    • 思路
    • 排序
    • 處理
    • 完整代碼
  • C++代碼實現
    • 排序
    • 完整代碼
  • 彩蛋

題目描述

小健有一家自己的商店,主營牛奶飲品,最近資金緊張,他想以盡可能低的價格進購足夠的牛奶以供日常的需要。所以小健想要求助你幫他想出一個最好的節省資金的辦法。
小健可以從幾個農場里購買牛奶,每個農場的牛奶都有自己的價格,每天的供應量也是有限的。小健只可以從每個農場里購買整數量的牛奶,且數量要小于等于農場的最大供應量。
給你小健每天所需要的牛奶總量,以及每個農場牛奶的單價和最大供應量,請你計算一下小健最少花多少錢就可以滿足自己的需求。
ps: 一定存在一個方案可以滿足小健的需求。


輸入

多組輸入,讀入到文件末。
每組的第一行兩個整數N and M.
第一個數 N (0 <= N <= 2000000) 小健每天的牛奶需求量. 第二個數 M (0 <= M <= 5000) 小健可以選擇購買的農場數.
每組的第二行到M+1行:每行兩個整數 Pi and Ai.
Pi (0 <= Pi <= 1000)農場i的牛奶單價.
Ai (0 <= Ai <= 2000000)農場i的最大供應量.


輸出

輸出可以滿足小健每天需求的最小錢數。


樣例輸入

100 5
5 20
9 40
3 10
8 80
6 30


樣例輸出

630


C語言代碼實現


思路

思路其實很簡單,做數學題嘛,先把每個農場的牛奶價格由低到高作升序排列,然后開始看第一個農場有的牛奶總量夠不夠小健的需求,不夠的話再去第二個農場買嘛,直到買夠為止。
拿這道題來講:
1、先做價格的排序(同時仍要將牛奶量與之對應)

3 10
5 20
6 30
8 80
9 40

10+20+30+40=100 也就是買到第四行的時候不必將80個全買下來,買40個就夠了

因此價格就等于10 * 3 + 20 * 5 + 30 * 6 + 40 * 8 = 630


排序

排序難點其實不在于排價格,價格從低到高排列,冒泡啊、插入啊、快排啊、都能解決,難點在于如何將價格排序的同時,將對應農場的牛奶量也進行相應的排序(因為采用的是兩個數組分別存價格和牛奶量),但仔細一想,也不難。排價格數組的時候順便把牛奶量數組的下標一改就行了。代碼如下:

void sort(int* a,int* b) {for(int m = 1; m < M; m++){int t = a[m];int q = b[m];for(int j=m;a[j]<a[j-1];j--){a[j]=a[j-1];a[j-1]=t;b[j]=b[j-1];b[j-1]=q;}}
}

處理

接下來就是簡簡單單的做小學數學題了。代碼如下:

int deal(int N,int* P,int* A) {mon=0;//價格重置for (int i = 0; i < M; i++) {int tmp = N < A[i]? N : A[i];//通過三目運算來擇取剩余需求和農場i牛奶量之間的最小值mon += tmp * P[i];//計算價格N -= tmp;//重新處理剩余需求}return mon;//最終返回所求的最低價格
}

完整代碼

#include <iostream>
#include <vector>
using namespace std;int N,M;//N需求量,M農場數
#define num 5003
int P[num];
int A[num];//P牛奶單價,A最大供應量
int mon;//最低價格int deal(int N,int* P,int* A) {mon=0;//價格重置for (int i = 0; i < M; i++) {int tmp = N < A[i]? N : A[i];//通過三目運算來擇取剩余需求和農場i牛奶量之間的最小值mon += tmp * P[i];//計算價格N -= tmp;//重新處理剩余需求}return mon;
}void sort(int* a,int* b) {for(int m = 1; m < M; m++){int t = a[m];int q = b[m];for(int j=m;a[j]<a[j-1];j--){a[j]=a[j-1];a[j-1]=t;b[j]=b[j-1];b[j-1]=q;}}
}int main(int argc, char const *argv[]) {while (cin >> N >> M) {for (int i = 0; i < M; i++) {cin >> P[i];cin >> A[i];}sort(P,A);deal(N,P,A);cout << mon << endl;}return 0;
}

C++代碼實現

思路都一樣,只是存儲價格和牛奶量的方法不再局限于數組,可以使用容器vector和結構模板pair,以及不用自己實現sort函數,可以直接調用algorithm里的sort函數。(ps:當然c語言也有qsort函數,但是STL是真的香啊~)


排序

寫一個compare函數的目的主要是為了便于自己理解sort函數的第三個參數,當然不寫自定義函數直接將sort的第三個參數寫成lambda表達式會更方便(也更難理解嚶嚶嚶)。哦此處提醒一下,從數學上來看,sort函數是一個左邊閉區間,右邊開區間的域,也就是如果有一個數組a[3],用戶想要給整個數組升序排序要寫成sort(a,a+3),眾所周知a[3]是a+2,當然用容器就不牽扯這個問題了。

bool compare(pair<int,int> a,pair<int,int> b){return a.first < b.first;//升序排列
}

完整代碼

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int N,M;//N需求量,M農場數
int mon;//最低價格bool compare(pair<int,int> a,pair<int,int> b){return a.first < b.first;
}int main(int argc, char const *argv[]) {while (cin >> N >> M) {vector<pair<int,int>> data(M);//data存儲牛奶單價(first)和最大供應量(second)for (int i = 0; i < M; i++) {cin >> data[i].first >> data[i].second;}sort(data.begin(),data.end(),compare);mon = 0;for (auto& tmp : data) {int num = N > tmp.second? tmp.second : N;mon += (num * tmp.first);N -= num;}cout << mon << endl;}return 0;
}

彩蛋

不需要compare的sort長什么樣呢?我明天就學lambda表達式好叭!

sort(res.begin(), res.end(),[](const pair<int, int>& cast1, const pair<int, int>& cast2){return cast1.first < cast2.first;});

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

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

相關文章

Eclipse 中修改java編譯版本

修改方法是&#xff1a; 1&#xff1a;Preferences-->Java-->Compiler->Compiler compliance level&#xff0c;選擇一個需要的版本&#xff0c;比如從默認的1.4改為5.0 2&#xff1a;如果只想修改一個工程的Compiler compliance level,就右單擊工程&#xff0c;選擇屬…

百戰c++(1)

Public和private的區別 public和private是類里的關鍵字&#xff0c;用于規定類內數據或者成員函數的訪問權限。private類型的數據或者函數&#xff0c;只能在相應的類內被訪問&#xff0c;而public類型的數據或者函數被訪問的權限比較寬&#xff0c;還可以在其它類或者其它函數…

一學就廢的三種簡單排序【冒泡、插入、選擇】

文章目錄其他排序算法冒泡排序算法實現代碼實例插入排序算法實現代碼實例選擇排序算法實現代碼實例其他排序算法 一學就廢的歸并排序 冒泡排序 排列順序從前到后或者從后往前都可&#xff0c;本文選擇從后到前的順序&#xff0c;升序排列&#xff1a;比較相鄰兩個元素&#x…

百戰c++(2)

delete 和 delete []的真正區別 delete 對應 new delete[]對應new[]對于簡單類型包括簡單類型數組&#xff0c;delete 與delete[]沒有區別。對于自定義類型數組&#xff0c;delete 只會刪除一個元素&#xff0c;delete 則會刪除所有元素。 指針和數組的區別 野指針是什么 野指…

shell預先定義的特殊變量

文章目錄$#$*$$$# 表示命令行上參數的個數&#xff0c;但不包括shell腳本名本身 為腳本ex1賦予兩個變量&#xff0c;測試$#的輸出結果 [cmybogon test2]$ . ex1 ma.c mb.c 2 # echo $# 7 # cat $1 $2 $3 | wc -l 2 # echo $#腳本ex1的具體內容 [rootlocalhost test]$ cat ex1…

Linux實驗一:常用的Linux命令

文章目錄一、實驗目的二、實驗要求三、實驗內容1、系統的使用2、命令的使用3、文件操作4、系統詢問與權限口令5、其它常用命令四、實驗操作1、基本命令的使用2、文件和目錄操作3、創建用戶帳戶一、實驗目的 1、熟悉Linux的桌面環境&#xff1b; 2、了解Linux所安裝的軟件包 3、…

Linux實驗二:vi編輯器的使用

文章目錄一、實驗目的二、實驗要求三、實驗內容1、創建文件2、編輯文件一、實驗目的 1、練習并掌握Linux提供的vi編輯器來編譯C程序 2、學會利用gcc、gdb編譯、調試C程序 3、本次實驗的目的是讓同學們了解如何使用vi編輯器進行創建和編輯文件 二、實驗要求 1、文件編輯器vi…

百戰c++(os1)

Linux中的鎖 互斥鎖&#xff1a;mutex&#xff0c;用于保證在任何時刻&#xff0c;都只能有一個線程訪問該對象。當獲取鎖操作失敗時&#xff0c;線程會進入睡眠&#xff0c;等待鎖釋放時被喚醒 讀寫鎖&#xff1a;rwlock&#xff0c;分為讀鎖和寫鎖。處于讀操作時&#xff0…

Linux實驗三:Shell編程

文章目錄一、實驗目的二、實驗要求三、實驗內容1、通配符的使用2、重定向3、管道4、shell變量5、建立下面的腳本&#xff0c;運行并分析輸出結果&#xff0c;并給出代碼注釋。6、編寫腳本一、實驗目的 1.為文件擴展名使用通配符 2.標準輸入、標準輸出和標準錯誤的重定向 3.使…

a href=#與 a href=javascript:void(0) 的區別

a href"#"> 點擊鏈接后&#xff0c;頁面會向上滾到頁首&#xff0c;# 默認錨點為 #TOP<a href"javascript:void(0)" onClick"window.open()"> 點擊鏈接后&#xff0c;頁面不動&#xff0c;只打開鏈接<a href"#" οnclick&…

Linux實驗四:編譯和調試工具的使用

文章目錄一、實驗目的&#xff1a;二、實驗要求三、實驗內容四、實驗操作1、用gcc編譯程序&#xff0c;寫出編譯過程&#xff0c;并給出運行結果。2、調試程序&#xff0c;要求用gdb進行調試并給出修改方案。3、make的使用一、實驗目的&#xff1a; 1、練習并掌握Linux提供的v…

Linux實驗五:Linux環境下的C語言編程

文章目錄一、實驗目的&#xff1a;二、實驗要求三、實驗內容1、編寫一段C語言程序使其完成&#xff1a;父進程創建兩個子進程&#xff0c;每個進程都在屏幕上顯示自己的進程ID號。2、上機調試下面的程序&#xff0c;觀察運行結果&#xff0c;分析原因。3、利用兩個管道進行雙向…

百戰c++(4)

1.求下面函數的返回值&#xff08;微軟&#xff09; int func(x) { int countx 0; while(x) { countx ; x x&(x-1); } return countx; } 假定x 9999。 答案&#xff1a;8 思路&#xff1a;將x轉化為2進制&#xff0c;看含有的1的個數。 2. 什么是“引用”&…

ndarray對象的建立

文章目錄ndarray&#xff08;別名array&#xff09;常用屬性創建NumPy數組使用array()函數使用zeros()函數使用ones()函數使用empty()函數使用arange()函數注意ndarray&#xff08;別名array&#xff09; 常用屬性 import numpy as np # Numpy工具包data np.arange(12).res…

百戰c++(5)

11. 已知strcpy的函數原型&#xff1a;char *strcpy(char *strDest, const char *strSrc)其中strDest 是目的字符串&#xff0c;strSrc 是源字符串。不調用C/C 的字符串庫函數&#xff0c;請編寫函數 strcpy。 答案&#xff1a; char *strcpy(char *strDest, const char *strS…

Numpy數組的廣播機制

文章目錄前言數組廣播廣播機制的使用條件前言 Numpy數組不需要循環遍歷&#xff0c;即可對每個元素執行批量的算術運算操作&#xff08;矢量化運算&#xff09;。當兩個數組大小&#xff08;Numpy.shape&#xff09;不同時&#xff0c;進行算術運算會出現廣播機制。 數組廣播…

百戰c++(6)

26. 描述內存分配方式以及它們的區別? 1&#xff09; 從靜態存儲區域分配。內存在程序編譯的時候就已經分配好&#xff0c;這塊內存在程序的整個運行期間都存在。例如全局變量&#xff0c;static 變量。 2&#xff09; 在棧上創建。在執行函數時&#xff0c;函數內局部變量的…

Spring3.1.0+Quartz1.8.6整合實現計劃任務

1.首先要加入任務計劃的相關的jar包&#xff0c;這里除了需要加Spring3.1.0的jar&#xff0c;還需要加quartz-all-1.8.6.jarslf4j-api-1.5.8.jar slf4j-log4j12.jar這三個包&#xff0c;如果你是SSH整合的項目&#xff0c;里面有下面的兩個包了&#xff0c;就可以不加&#xff…

百戰c++(7)

40. 鏈表題&#xff1a;一個鏈表的結點結構 struct Node { int data ; Node *next ; }; typedef struct Node Node ; (1)已知鏈表的頭結點head,寫一個函數把這個鏈表逆序 ( Intel) Node * ReverseList(Node *head) //鏈表逆序 { if ( head NULL || head->next NU…

數組的轉置和軸對稱

文章目錄T屬性transpose()方法swapaxes()方法T屬性 import numpy as np # Numpy工具包data np.arange(12).reshape(3, 4) # 創建一個3行4列的數組 print(data)# 數組的轉置和軸對稱 data1 data.T print(data1)print(data) [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] print(dat…