洛谷·P1094 纪念品分组 python代码

附上代码

w = eval(input())#最大的礼物价格
n = eval(input())#礼物个数
ls = []
for i in range(n):#向列表中加入礼物
    temp = eval(input())
    ls.append(temp)
ls = sorted(ls)#使用sorted函数将列表排序
i = 0#指向列表的第一个元素
p = n - 1#指向列表的最后一个元素
pack = 0#礼物包数
while(i <= p):
    temp2 = ls[i] + ls[p]#temp2来储存暂时的价格
    if temp2 <= w and p - i > 1:  #在i和p没有相遇的时候且两个礼物价格之和小于最大值
        pack += 1
        i += 1
        p -= 1
        temp2 = 0
    elif temp2 <= w and p - i == 1:  #i和p刚好相遇的时候且两个礼物价格之和小于最大值
        pack += 1
        break
    elif temp2 > w and p - i > 1:   #i和p没有相遇且单个礼物价格大于最大值
        pack += 1
        p -= 1
        temp2 = 0
    elif temp2 > w and p - i == 1:  #i和p相遇且单个礼物价格大于最大值
        pack += 2
        break
    elif i == p:  #i和p重合(两个指针指向同一个列表元素)
        pack += 1
        break

print(pack)

删除线格式
做这道贪心题可以使用双指针法,因为要保证每一包礼物的价格尽可能大,又不能超过最大值,可以想到将价值最高的和价值最低的打为一包,价值第二高的和第二低的打为一包,
所以就对列表进行排序处理,这里我用了python自带的sorted函数,排序之后,设置两个指针i p,分别指向列表的第一位和最后一位,这里要注意,每包最多放两个礼物,
所以,如果i所指的和p所指的相加小于最大值,就将i和p指的礼物打成一包,然后i递增,p递减。
如果相加大于最大值,就把价值大的单独打成一包,然后p递减,i不变。
最后的时候会有特殊情况,比如最后只剩下一个或者最后i和p的值相同的处理情况,在上附的代码中都可以找到。
双指针法在贪心和排序问题中都有比较广泛的用法(快排就是用双指针实现的),该方法值得一看。
就这样了,溜了溜了~~

你可能感兴趣的:(洛谷·P1094 纪念品分组 python代码)