【贪心算法】一文让你学会“贪心”(贪心算法详解及经典案例)

1.接水时间最短问题

题目描述
有n个人在一个水龙头前排队接水,假如每个人接水的时问为T,请编程找出这n个人排队的一种顺序
使得n个人的平均等待时间最小。
输入格式
第一行为一个整数n。
第二行n个整数,第i个整数T表示第i个人的接水时间T
输出格式
输出文件有两行,第一行为一种平均时间最短的排队顺序:第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。

说明/提示
1≤n≤1000.1≤t≤10,不保证t不重复
代码展现

n=int(input())
b=list(map(int,input().split()))
c=[]
for i in range(n):
	c.append([i+1,b[i]])
	c.sort(key=lambda x:x[1])
ans=0
for i in range(n):
	if(i!=n-1):
		print(c[i][0],end='')
	else:
		print(c[i][0])
for i in range(n):
	ans+=c[i][1]*(n-i-1)
ans/=n
print(f"{ans:.2f}")


2.糖果数量有限问题

题目描述
小A有n个糖果盒,第i个盒中有Ai颗糖果,小A每次可以从其中一盒糖果中吃掉一颗,他想知道,要让任意两个相邻的盒子中的糖果个数之和都不大于x,至少得吃掉几颗糖。
输入格式
输入的第一行是两个用空格隔开的整数,代表糖果盒的个数n和给定的参数x。
第二行有n个用空格隔开的整数,第i个整数代表第i盒糖的糖果个数Ai。
输出格式
输出一行一个整数,代表最少要吃掉的糖果的数量,
思路提醒
此处的贪心策略考虑到的是先不考虑相邻糖盒的糖果数量差异极端的情况,也就是左边很多,右边为零,或右边被吃完后为负的情况,之后再通过if-else结构把这种情况考虑到。
代码展现

n,x=map(int,input().split())
a=list(map(int,input().split()))
ans=0
for i in range(n-1):
	if(a[i]+a[i+1]>x):
		temp=a[i]+a[i+1]-x
		ans+=temp
		if(a[i+1]>=temp):
			a[i+1]-=temp
		else:
			a[i]-=(temp-a[i+1])
			a[i+1]=0
print(ans)


3.分发时间最短问题

题目描述
元旦快到了,校学生会让乐乐负责新年会的纪念品发放工作。为使得参加晚会的同学所获得的纪念品价值相等均衡,要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品,并且每组纪念品的价格之和不能超过一个给定的整数。为了在尽量短的时间内发完所有的纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分面数最少的一种,出最少的分组数目。
输入格式
其n+2行:
第一行包括一个整数w,为每组纪念品价格之和的上限
第二行为一个整数n,表示购来的纪念品的总件数G
第3~n+2行每行包含一个正整数Pi表示所对应纪念品的价格
输出格式
一个整数,即最少的分组数目,
代码实现

w=int(input())
n=int(input())
h=[]
for i in range(n):
    h.append(int(input()))
h.sort()
l,r=0,len(h)-1
ans=0
while(l<=r):
    if(h[l]+h[r]<=w):
        ans+=1
        h+=1
        r-=1
    else:
        ans+=1
        r-=1
print(ans)

4.采摘苹果最多问题

题目描述
又是一年秋季的,陶陶家的果树结了n个果子,陶陶又跑去摘苹果,这次他有一个a公分的椅子,当他手够不看时,他会站到椅子上再试试。
这次与NOIp200S普及组第一题不同的是:陶陶之前搬凳子,力气只剩下了s,当然,每次摘苹果时都要用一定力气。陶陶想知道在s<0之前最多能摘到多少个苹果。
现在已知n个苹果到达地上的高度Xi,椅子的高度a,陶陶手伸直的最大长度b,陶陶所剩的力气s,陶陶摘一个苹果需要的力气Yi,求陶陶最多能摘到多少个苹果。
输入格式
第1行:两个数 苹果数n,力气s
第2行:两个数 椅子的高度a,陶陶手伸直的最大长度b
第3行~第3+n-1行:每行两个数 苹果高度Xi,摘这个苹果需要的力气Yi。
输出格式
只有一个整数,表示陶陶最多能摘到的苹果数,
代码实现

n,s=map(int,input().split())
a,b=map(int,input().split())
pg=[]
for i in range(n):
    x,y=map(int,input().split())
    pg.append([x,y])
pg.sort(key=lambda x:x[1])
ans=0
for temp in pg:
    if(temp[0]<=a+b and s>=temp[1]):
        ans+=1
        s-=temp[1]
print(ans)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值