一道很简单的贪心算法题~【贪心:我不要脸的伐?】

文章目录

  • 题目描述
  • 输入
  • 输出
  • 样例输入
  • 样例输出
  • 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.mzph.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…