基础算法
来源:互联网 发布:压缩包密码破解 知乎 编辑:程序博客网 时间:2024/06/03 21:28
前言
贪心贪心,顾名思义,就是说你要很贪 (当然你可能会被抓)
不同于 动态规划 的目光长远,贪心 往往“鼠目寸光”,只注重眼前的利益
而这也是贪心的定义:
在当前情况下寻找 局部 最优解
所以当你确定一道题目是贪心时,不要想太多,每次取最优即可
纵使后面可能会有更好的情况,那也不关咱们的事 (谁让咱们贪呢)
当然有一些贪心题看起来很像dp,千万别搞混(比如例题第一题)
例题
Luogu P2095 营养膳食
注意:这题不是dp,这题不是dp,这题不是dp!
(我还信誓旦旦地说这是背包来着)
第一遍看我就只想到了 dp ,写了 10min 之后发现 dp 完全无法实现
所以这题是贪心无疑
那么我们怎么贪呢?
大家应该还记得贪心的定义,所以我们每次只要吃脂肪尽可能多的就可以了
做法:
1. 读入每种食物最多吃多少份
2. 读入食物的脂肪和种类
3. 按脂肪排序(核心部分 非常重要)
4. 排序部分我们从大到小排,所以从第一份开始判断(i from 1 to m)
5. 先判断还能不能吃这一种
6. 再判断有没有越界(
7. 符合条件直接加上即可
写完之后我们会发现,得出的就是最优解,因为脂肪最多的那些都被我们吃掉了
代码仅供参考:
#include<cstdio>#include<algorithm>//使用sort函数using namespace std;int n,m,k,Max_Eat[105],ans;struct node//创建结构体存信息{ int Fat,Type;//脂肪和种类}a[205];bool cmp(node x,node y)//sort的判断用函数{ return x.Fat>y.Fat;//从大到小排}int main(){ scanf("%d %d %d",&n,&m,&k); for(int i=1;i<=k;i++) scanf("%d",&Max_Eat[i]); for(int i=1;i<=n;i++) scanf("%d%d",&a[i].Fat,&a[i].Type);//读入数据 sort(a+1,a+n+1,cmp);//核心的排序部分 int tot=1;//tot代表现在吃到了第几份 for(int i=1;i<=m;i++)//最多吃m份 { if(Max_Eat[a[tot].Type]>0 && tot<=n)//如果符合条件 { ans+=a[tot].Fat;//直接加上 Max_Eat[a[tot].Type]--;//这一步也很重要,当前种类能吃的份数-1 tot++;//到下一份 } else tot++;//如果不能吃也到下一份 } printf("%d",ans);//输出即可 return 0;}
再来一道:
Luogu P2695 骑士的工作
这道题目是一题比较明显的贪心,我们需要让每个骑士砍掉他所能砍的最小的头
那么有人就要问了:这怎么实现呢?
排序呗!
(实际上大多贪心的题目都要用到排序,sort是一个必须要学的东西)
做法:
1. 读入每个骑士能砍的头的大小
2. 读入龙头的大小
3. 分别排序(核心代码 从小到大排)
4. 对每个骑士进行判断,让他砍掉他所能砍的最小的头
5. 如果能砍
6. 如果
当然我们可以进行一些小小的优化
注意:每个骑士只能砍一个龙头
代码仅供参考:
#include<cstdio>#include<algorithm>//sort大法好using namespace std;int n,m,d[20005],k[20005],ans,sum;bool used[20005];int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&d[i]); for(int i=1;i<=m;i++) scanf("%d",&k[i]);//读入数据 if(n>m)//小优化,如果骑士比恶龙少直接就可以放弃治疗【划掉】退出程序了 { printf("you died!"); return 0; } sort(d+1,d+n+1); sort(k+1,k+m+1);//排序 for(int i=1;i<=n;i++) { bool Can_Kill=false;//用来存储能不能砍掉龙头 for(int j=1;j<=m;j++) { if(used[j]) continue;//used数组存储龙头是否已经被砍 if(k[j]>=d[i])//由于排序过,所以第一个能砍的必然是能砍的最小的头 { ans+=k[j];//费用加上 Can_Kill=true;//能杀 sum++;//又杀了一头 used[j]=true;//这头龙已死 break;//退出循环 } } if(!Can_Kill)//不能杀的话直接 欢声笑语中打出GG { printf("you died!"); return 0; } } if(sum==n) printf("%d",ans); else printf("you died!");//判断输出即可 return 0;}
小结
贪心不论是在 日常刷题 还是在 竞赛 中,使用都非常广泛
相信参加过竞赛(甚至是模拟赛)的同学都知道贪心是一种十分优秀的骗分方法
所以贪心还是有必要多学多练的
原创 By Venus
写的不好大佬轻喷
- 算法基础
- 算法基础
- 算法基础
- 基础算法
- 算法基础
- 基础算法
- 基础算法-
- 基础算法
- 算法基础
- 算法基础
- 基础算法
- 基础算法
- 算法基础
- 基础算法
- 基础算法
- 基础算法
- 基础算法
- 算法基础
- django excel 导出
- JS实现Base64加解密
- 技术分享连载(七十七)
- spi核心层驱动模型简述
- jQuery $.proxy() 方法
- 基础算法
- spring实现事物的回滚
- 乡村美食传播想法
- Xshell 快捷键
- SpringBoot使用Shiro验证登录笔记
- ubuntu chinese input
- 嵌入式媒体处理(EMP)中的编码和解码
- RPM包操作
- 将16进制的数按字符格式存储,转换为10进制数输出-C语言