贪心算法小结2

F-Ants

一队蚂蚁在一根水平杆上行走,每只蚂蚁固定速度 1cm/s. 当一只蚂蚁走到杆的尽头时,立即从秆上掉落. 当两只蚂蚁相遇时它们会掉头向相反的方向前进. 我们知道每只蚂蚁在杆上的初始位置, 但是, 我们不知道蚂蚁向哪个方向前行. 你的任务是计算所有蚂蚁都杆上掉落可能的最短时间和最长时间.

Input

第一行包含一个整数,给出测试实例数量. 每组数据开始有两个整数: 杆的长度 (单位:cm) 和杆上蚂蚁数量 n. 之后是 n 个整数给出每只蚂蚁从杆的最左边开始的位置, 且是无序的. 输入的每个整数都不大于 1000000 ,两个数字用空格分开.

Output

对于每组输入输出两个整数. 第一个整数表示所有蚂蚁从杆上掉落可能的最短时间(如果它们前行方向选择得当) ,第二个整数表示可能的最长时间.

Sample Input

2
10 3
2 6 7
214 7
11 12 7 13 176 23 191

Sample Output

4 8
38 207
  解题思路:这个题想明白一点就好写了。即蚂蚁的速度是一样的,转身不消耗时间,那么可以将两只相遇时掉头的蚂蚁,看做交错而过,不理会相遇即可。因为掉头与交错而过的时间是一样的。再暴力搜素每一个蚂蚁的位置,如果是最短时间,则比较
它距杆左边的距离与距杆右边的距离取最小,取出最大的最小值,即为所求 。如果是最长时间,比较它与杆左边的距离与杆右边的距离取最大,最后取出最大值。代码如下:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <map>
#include <stack>
#include <utility>
using namespace std;
int const max_n=500;
int a[max_n];
int main()
{int m,n,t;scanf("%d",&t);while(t--){cin>>m>>n;for(int i=0;i<n;i++)cin>>a[i];int minN=0,maxN=0;//最短时间,最长时间for(int i=0;i<n;i++)minN=max(minN,min(a[i],m-a[i]));for(int i=0;i<n;i++)maxN=max(maxN,max(a[i],m-a[i]));cout<<minN<<" "<<maxN<<endl;memset(a,0,sizeof(a));}return 0;
}

 G-Fence Repair

Description

It is universally accknowledged that 泥煤(peat)是一个非常珍贵的收藏品,越大的泥煤收藏价值越高。

一天,王泥煤找到了阿拉伯神灯,也就是阿拉丁神灯的弟弟,他向阿拉伯神灯许了一个愿望,从此获得了一个超能力,可以将两个泥煤合并为更大的泥煤。但是这个能力非常的鸡肋,王泥煤需要支付与这两块泥煤等价值的财富才能将他们合并。

比如:王泥煤把两块价值分别为3和5的泥煤合并,可以得到一块价值为8的泥煤,但是要消耗3+5的财富。

王泥煤想知道,他将手中的n块泥煤合并到只剩下一块之后,最少需要花费多少财富。

Input

第一行为一个整数n(n <= 20000),代表王泥煤拥有的泥煤数量,接下来n行,每行一个整数a_i(1 <= a_i <= 50000),代表每个泥煤的价值

Output

输出包括一行,请告诉王泥煤他需要花费的最少财富。

Sample Input

3
8
5
8

Sample Output

34
   解题思路:就是不断选取最小的两块煤进行合成,合成后放入煤堆再找两个最小的,如果取一次排序一次,时间复杂度太高o(n^2),因此要用到优先队列 ,注意使用默认的greater 按升序排序就可以了。注意数据范围,要开long long 代码如下:
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define LL long long
using namespace std;
int main()
{int n,x;LL maxq=0;scanf("%d",&n);priority_queue<LL,vector<LL>,greater<LL> >q;for(int i=0;i<n;i++){scanf("%d",&x);q.push(x);}while(q.size()!=1){LL a,b;a=q.top();q.pop();b=q.top();q.pop();LL c=a+b;q.push(c);maxq+=c;}cout<<maxq<<endl;return 0;
}

 H-最少拦截系统

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统. 

Input输入若干组数据.每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔) 
Output对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统. 
Sample Input

8 389 207 155 300 299 170 158 65

Sample Output

2
  解题思路:因为不能漏掉任何一个导弹,所以要从第一个导弹开始,构建一个下降子序列;而在构建下降过程中的导弹若高于上一个导弹,则必须要使用新的拦截系统。这题我一开始写的挺复杂的,过了之后看题解,发现自己想复杂了,可以开一个数组,输入一个
导弹高度 ,若高于现在所有的拦截系统的高度,则必须新开一个拦截系统;若有拦截系统能够拦下它,则更新该拦截系统的高度。参考链接:https://blog.csdn.net/sdut_jk17_zhangming/article/details/79292887
代码如下:
#include<stdio.h>int main()
{int a[300] = {0},i,n,j,h,m;while(scanf("%d",&n) != EOF){m = 0;for(i= 0;i <n;i++){scanf("%d",&h);for(j = 0;j <m;j++){if(a[j] >= h)break;}if(j <m)a[j] = h;else{a[m] = h;m++;}}printf("%d\n",m);}return 0;
}

  写题的过程中,有不会的是很正常的,若是自己能写过,就坚持写完,写完找找题解,了解别人的思路再与自己的思路对比,最好能学到最优解。所有做题过程中不要太过于纠结题解问题,关键在于看了有没有学会最优解(或者说相对较好的思路)。

 

J - Packets

 
一家工厂生产的产品规格分为1×1, 2×2, 3×3, 4×4, 5×5, 6×6,高都是h。工厂要把它们包在6×6×h的包装袋中。工厂想让包装数尽可能少。

Input

多组数据。每一行为一组数据。依次是1×1, 2×2, 3×3, 4×4, 5×5, 6×6的产品的个数。 输入数据由6个0结束。

Output

对于每组数据,输出包装所有产品所需最少包装袋数量

Sample Input

0 0 4 0 0 1 
7 5 1 0 0 0 
0 0 1 0 1 0
0 0 0 0 0 0 

Sample Output

2 
1
2 

   思路:这是一道二维装箱题,而装箱问题一般来说比较复杂,如果针对每一种情况进行精确算法是非常繁琐且容易出错的。在这里我用到了ceil()函数,返回大于或等于表达式值的函数来简化算法。(参考链接http://blog.csdn.net/c20190413/article/details/77396357###)首先看,4×4,5×5,6×6的箱子,很显然这三种箱子没有一个就要占用一个包装袋,6×6的箱子直接占用一个包装袋,而5×5的箱子则可以塞进去11个1×1的箱子,用1×1箱子的个数减去min(a,e*11)(a为1×1箱子个数,e为5×5箱子个数,为表述方便,依次为箱子编号a、b、c、d、e、f);对于一个4×4箱子,可以塞进2×2的箱子5个,若2×2箱子数不足时,可以补充1×1箱子;b-=min(b,d*5),若2×2箱子数不足时则有a-=min(a,4*(d*5-b))。

  然后看3×3的箱子,分四种情况,箱子数为4的倍数,除以4余3、余2、余1,3种情况,这里选余2的情况为例子阐述。这时还有若干个1×1箱子若干个2×2箱子,两个3×3箱子;分析易知,此时最多可以放入3个2×2箱子,最少放入6个1×1箱子才能把包装袋填满。首先判断2×2箱子剩余数量有没有3个,不足3个的部分,用1×1箱子补充,不足时有a-=min(a,(3-b)*4);然后进行a-=min(a,6);b-=min(b,3)。其余情况依此类推。使用min函数保证不出现负数。剩余的就是若干个1×1箱子和2×2箱子,使用ceil函数可以很快解决。代码如下:

 

#include <iostream>
#include <algorithm>
#include <math.h>
#define LL long long
int const max_n=20;
using namespace std;
int main()
{int a,b,c,d,e,f;while(1){cin>>a>>b>>c>>d>>e>>f;if(!a&&!b&&!c&&!d&&!e&&!f)break;int num=0;num=d+e+f;a-=min(a,e*11);//减去应补充e箱子的a箱子if(b<d*5)a-=min(a,4*(d*5-b));//b箱子不足时,使用a箱子b-=min(b,d*5);//减去补充d箱子的b箱子num+=ceil(c/4.0);//向上取整c%=4;if(c==1){//多余1个3×3的箱子时if(b<5)a-=min(a,4*(5-b));//先判断b箱子数量是否足够a-=min(a,7);b-=min(b,5);}else if(c==2){//多余2个3×3的箱子时if(b<3)a-=min(a,4*(3-b));a-=min(a,6);b-=min(b,3);}else if(c==3)//多余3个3×3的箱子时
        {if(!b)a-=min(a,4);a-=min(a,5);b-=min(b,1);}num+=ceil(b/9.0);b%=9;if(b)a-=min(a,(9-b)*4);num+=ceil(a/36.0);printf("%d\n",num);}return 0;
}

 

N - Stall Reservations

 
这里有N只 (1 <= N <= 50,000) 挑剔的奶牛! 他们如此挑剔以致于必须在[A,B ]的时间内产奶(1 <= A <= B <= 1,000,000)当然, FJ必须为他们创造一个决定挤奶时间的系统.当然,没有牛想与其他奶牛分享这一时光 

帮助FJ做以下事:
  • 使每只牛都有专属时间的最小牛棚数
  • 每只牛在哪个牛棚
也许有很多可行解。输出一种即可,采用SPJ
Input
第一行一个数字 N 

第 2..N+1行: 第 i+1行 描述了i号奶牛挤奶的起止时间
Output
第一行:牛棚最小数量 

Lines 2..N+1: 第 i+1行 描述了i奶牛被安排的牛棚
Sample Input
5
1 10
2 4
3 6
5 8
4 7
Sample Output
4
1
2
3
2
4
Hint
样例解释: 

这里是一种图示 

Time     1  2  3  4  5  6  7  8  9 10

Stall 1 c1>>>>>>>>>>>>>>>>>>>>>>>>>>>
Stall 2 .. c2>>>>>> c4>>>>>>>>> .. ..
Stall 3 .. .. c3>>>>>>>>> .. .. .. ..
Stall 4 .. .. .. c5>>>>>>>>> .. .. ..
其他的也是可能的

   思路:这是一道牛奶分栏问题,分栏不算难,难点在于如何描述某只奶牛在哪个牛棚中。有两种贪心策略,一:以最早开始的奶牛进行计算,在该奶牛产奶结束后

选取离这个结束时间最近且的奶牛,安排其进行产奶,直至某个牛的结束时间大于或等于规定时间,开始为下一个牛棚安排;这种策略实际上是以牛棚为出发点,通过使用最少的牛棚让更多的牛产奶,直到所有奶牛都产过奶了;实现要用set或数组,进行一个牛棚的安排后,要对在该牛棚产奶的牛进行删除。二:将奶牛以产奶时间的早晚进行排列,在时间顺序上让每一个奶牛在产奶时间都能有牛棚产奶,若有空闲牛棚,则安排改产奶的奶牛去产奶,若是没有空闲牛棚,就要准备新的牛棚;通过优先队列以及对队列的维护实现。这里我是用了优先队列,实现代码如下:

#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#define LL long long
int const max_n=50002;
using namespace std;
struct Node{int st,ed,id,stal;//开始时间,结束时间,奶牛编号,牛棚号bool operator <(const Node &a)const{//这是优先队列中一个排序方式,重载<用来排序,维护优先队列return a.ed<ed;    }
}cow[max_n];
bool cmp(Node a,Node b)//结构体比较函数
{if(a.st!=b.st)return a.st<b.st;return a.ed<b.ed;
}
int main()
{int n,a[max_n];scanf("%d",&n);priority_queue<Node> q;//下标由1开始,方便计算和思考for(int i=1;i<=n;i++){scanf("%d %d",&cow[i].st,&cow[i].ed);cow[i].id=i;}sort(cow+1,cow+n+1,cmp);cow[0].stal=1,cow[0].ed=0;q.push(cow[0]);int i=1,k=2;//初始化牛棚数为2while(i<=n){Node c=q.top();if(cow[i].st>c.ed)//当某个牛的开始产奶时间大于队列中最早结束时间,即这个牛产奶开始时有空闲牛棚
        {q.pop();cow[i].stal=c.stal;a[cow[i].id]=c.stal;q.push(cow[i]);}else{//没有空闲牛棚,安排新牛棚cow[i].stal=k;a[cow[i].id]=k++;q.push(cow[i]);}i++;}printf("%d\n",k-1);for(int i=1;i<=n;i++)printf("%d\n",a[i]);return 0;
}

 

 

O - Yogurt factory

奶牛们收购了一家世界著名的酸奶工厂Yucky Yogurt. 在接下来的 N (1 <= N <= 10,000) 周,牛奶和人工的价格每周会波动,以致于第i周需要花公司 C_i (1 <= C_i <= 5,000) 美分来生产一个单位的酸奶. Yucky factory被奶牛们照顾得很好,所以每周可以生产很多单位的酸奶 

Yucky Yogurt 拥有一个仓库,可以以S (1 <= S <= 100)美分每单位每周的价格储存没用的酸奶。神奇的是,酸奶不会变质。而且仓库十分巨大,可以容纳很多牛奶 

Yucky Yogurt每周要交货 Y_i (0 <= Y_i <= 10,000) 单位的酸奶给它的客户。请你帮助奶牛们减少整个 N-week 期间的支出. i周生产的牛奶和之前储存的牛奶都可以用来交i周的货

Input

* 第一行:N and S. 

* 第 2..N+1行:第 i+1 行包括 : C_i 和 Y_i.

Output

* 满足客户需求的最小花费,保证不超过64位整数

Sample Input

4 5
88 200
89 400
97 300
91 500

Sample Output

126900

Hint

输出提示: 
第一周生产200单位,全部售出。第二周生产700单位,售出400,储存300.第三周使用储存的300单位。第四周,生产500单位并全部售出 
注释:
yucky意为难以下咽的

 

   思路:贪心策略为,在本周的人工成本较低下周时(即生产下周要交货的奶加上存储的钱仍比下周生产牛奶价格低时),在本周多生产下周要交货的牛奶数,并存在仓库里。其他情况,就老老实实生产足够本周交货的奶,因为一般情况下不考虑生产后两周的牛奶加上存两周牛奶的钱比下下周的生产成本低的情况。代码如下:

#include <iostream>
#include <algorithm>
#define LL long long
int const max_n=10002;
using namespace std;
struct node{int c,y;
}num[max_n];
int main()
{int n,s;scanf("%d %d",&n,&s);for(int i=0;i<n;i++)scanf("%d %d",&num[i].c,&num[i].y);int i=0;LL mony=0;while(i<n){if(num[i].c*num[i+1].y+s*num[i+1].y<num[i+1].c*num[i+1].y){mony+=num[i].c*num[i+1].y+s*num[i+1].y;num[i+1].y=0;}mony+=num[i].c*num[i].y;i++;}cout<<mony;return 0;
} 

 

 

转载于:https://www.cnblogs.com/whocarethat/p/11015649.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/386654.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

掌握这些Android开发热门前沿知识,跳槽薪资翻倍

前言 这是一篇软文、但是绝对不是鸡汤&#xff1b;为啥不是呢&#xff1f;因为我文笔太差…偶尔矫情发发牢骚&#xff08;勿喷&#xff09; 说说程序猿行业 现在社会上给IT行业贴上了几个标签&#xff1a;高薪、高危、高大上、秃顶&#xff08;哈哈&#xff09;。这些标签我…

linux环境-docker安装rabbitmq

1、进入docker hub镜像仓库地址&#xff1a;https://hub.docker.com/ 2、搜索rabbitMq&#xff0c;进入官方的镜像&#xff0c;可以看到以下几种类型的镜像&#xff1b;我们选择带有“mangement”的版本&#xff08;包含web管理页面&#xff09;&#xff1b; 3、拉取镜像 doc…

揭秘ARouter路由机制,源码+原理+手写框架

前言 每个程序员都有一个梦想&#xff0c;那就是进一线互联网公司深造&#xff0c;不要跟我说你不想进去&#xff0c;如果给你一个这样的平台&#xff0c;不管是薪资待遇还是接触的高度来说&#xff0c;对我们程序员来说都是一个机会&#xff0c;我以前有一个同事&#xff0c;…

docker 安装 nacos/nacos-server 镜像并配置本地数据库

docker pull nacos/nacos-server 启动镜像 这里启动容器的时候参数配置我就不在详解了&#xff0c;不明白的话&#xff0c;评论区留言&#xff0c;有不会的问题一定要及时询问&#xff0c;期待你的评论呦&#xff01; docker run --env MODEstandalone --name nacos -d -p 884…

初中 英文

英语过去式与过去完成进行时是在英语语法学习中&#xff0c;非常重要的两种语法&#xff0c;直接影响着英语能力的好坏。熟练掌握这两种语法对于学习者来说是至关重要的&#xff0c;今天就为大家整理了有关英语过去式与过去完成进行时的相关用法解析&#xff0c;希望大家可以认…

揭秘!双非渣本Android四年磨一剑,学习路线+知识点梳理

第一次观看我文章的朋友&#xff0c;可以关注、点赞、转发一下&#xff0c;每天分享各种干货技术和程序猿趣事 由于涉及到的面试题较多导致篇幅较长&#xff0c;我根据这些面试题所涉及到的常问范围总结了并做出了一份学习进阶路线图​​​​​​​及面试题答案免费分享给大家&…

Windows上PostgreSQL安装配置教程

这篇文章主要为大家详细介绍了Windows上PostgreSQL安装配置教程&#xff0c;具有一定的参考价值&#xff0c;感兴趣的小伙伴们可以参考一下 PostgreSQL的扩展PostGIS是最著名的开源GIS数据库。 安装PostgreSQL是第一步。 1.下载PostgreSQL的二进制安装文件。 PostgreSQL官网…

快递100接口的调用过程

前言 大部分的商城都需要调用快递的接口来记录商城的物流信息&#xff0c;这里就给出一种快递接口&#xff08;快递100&#xff09;调用的方法。 正文 一、官方文档 1. 官方文档的地址为&#xff1a; https://www.kuaidi100.com/openapi/api_subscribe.shtml 二、具体实现 1. 商…

搞懂开源框架设计思想真的这么重要吗?终获offer

正文 从我个人的角度写写30多岁码工的感受&#xff1a;的确是受年龄压力开始增大了。比如二十多岁的小年轻&#xff0c;可能什么都懂&#xff0c;对组里的东西很熟悉。有时候我也怀疑自己是不是智商不够&#xff0c;是不是自学能力太差&#xff0c;是不是基础不行&#xff0c;…

gitlab 修改HTTP连接方式中的IP和端口

修改gitlab.yml文件 cd /opt/gitlab/embedded/service/gitlab-rails/config vim gitlab.yml 修改gitlab host&#xff1a;要修改的IPport&#xff1a;要修改的端口重启gitlab gitlab-ctl restart

Coding Interview Guide -- 向有序的环形单链表中插入新节点

【题目】 一个环形单链表从头节点head开始不降序&#xff0c;同时由最后的节点指回头节点。给定这样一个环形单链表的头节点head和一个整数num&#xff0c;请生成节点值为num的新节点&#xff0c;并插入到这个环形链表中&#xff0c;保证调整后的链表依然有序 1 public Nod…

真香定律!Android动态换肤实现原理解析,原理+实战+视频+源码

自己项目中一直都是用的开源的xUtils框架&#xff0c;包括BitmapUtils、DbUtils、ViewUtils和HttpUtils四大模块&#xff0c;这四大模块都是项目中比较常用的。最近决定研究一下xUtils的源码&#xff0c;用了这么久总得知道它的实现原理吧。我是先从先从BitmapUtils模块开始的。…

使用Docker启动Grafana环境

docker search grafana docker pull grafana/grafana docker imagesdocker run -d -p 3000:3000 grafana/grafana 启动成功,进入本机浏览器访问 http://localhost:3000 使用admin/admin进入系统

js包装类型的装箱拆箱

https://www.jb51.net/article/155820.htm https://juejin.im/post/5cbaf130518825325050fb0a https://juejin.im/post/5ccfb58f518825405a198fcd转载于:https://www.cnblogs.com/little-ab/p/11025952.html

真香定律!Android动态换肤实现原理解析,吐血整理

自己项目中一直都是用的开源的xUtils框架&#xff0c;包括BitmapUtils、DbUtils、ViewUtils和HttpUtils四大模块&#xff0c;这四大模块都是项目中比较常用的。最近决定研究一下xUtils的源码&#xff0c;用了这么久总得知道它的实现原理吧。我是先从先从BitmapUtils模块开始的。…

knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案

knife4j knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名kni4j是希望它能像一把匕首一样小巧,轻量,并且功能强悍! knife4j的前身是swagger-bootstrap-ui&#xff0c;为了契合微服务的架构发展,由于原来swagger-bootstrap-ui采…

调试与对拍(一):生成测试数据+对拍

今天打比赛时令小编很气愤&#xff0c;隔壁LSH有文件运行错误&#xff0c;重提了一遍老师就收&#xff0c;而小编重提却爱搭不理&#xff0c;于是小编决定还是自己造个数据把代码重测一遍&#xff0c;于是潜心钻研生成测试数据的方法。 其实很简单&#xff0c;用随机数生成器生…

真香定律!一文带你搞懂Android多线程Handler,成功入职腾讯

Google 为了帮助 Android 开发者更快更好地开发 App&#xff0c;推出了一系列组件&#xff0c;这些组件被打包成了一个整体&#xff0c;称作 Android Jetpack&#xff0c;它包含的组件如下图所示&#xff1a; 老的 support 包被整合进了 Jetpack&#xff0c;例如上图 Foundatio…

Docker安装influxDB

1. 在Docker库中查找influxDB镜像 docker search influxdb # 在Docker库中查找influxDB镜像文件 从Docker库中拉取influxDB镜像 docker pull influxdb # 从docker库中拉取influxDB镜像&#xff0c;默认拉取最新版本 docker images …

(二十)python 3 匿名函数

匿名函数lambda Python使用lambda关键字创造匿名函数。所谓匿名&#xff0c;意即不再使用def语句这样标准的形式定义一个函数。这种语句的目的是由于性能的原因&#xff0c;在调用时绕过函数的栈分配。其语法是&#xff1a; lambda [arg1[, arg2, ... argN]]: expression 其中&…