leetcode 贪心策略

本质:每步只选择当前最优解
贪心:不记录历史状态,只关心当前状态;动态规划:需要记录历史状态,在将来会被用到。
1.问题描述(过河问题)

在漆黑的夜里,甲乙丙丁共四位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥的。不幸的是,四个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,四人所需要的时间分别是1、2、5、8分钟;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题:如何设计一个方案,让这四人尽快过桥。

解题思路:
假定四个人过河时间是T1,T2,T3,T4T1<T2<T3<T4,如何选择过桥方案。

第一种过河方法的总时间为:T2+T1+T3+T1+T4

第二种过河方法的总时间为:T2+T1+T4+T2+T2
这两次方案的差异:次快的人要不要也传递一次手电筒。
结论:根据二者之差为:(T1+T3)-2T2,选择过河方式

一般情况:
现在我们把这个问题推广:如果有N(N大于等于4)个旅行者,假设他们有各自所需的过桥时间有快有慢,各不相同。在只有一只手电筒的情况下,要过上述的一条桥,怎样才能找到最快的过桥方案?

现在我们假定,N个人单独过桥的时间分别是T1,T2,T3,……,Tn,且满足T1<T2<T3<…… <Tn。

经过分析,要满足最快过桥,合理的安排包括以下几点:

1)让最快的送手电筒的次数尽可能多些。

2)某些方案中,次快的也送电筒也可能会电筒。

3)让慢的过桥次数尽可能少些;

4)最快的两个先过桥,以保证此二人是能来回送电筒的人;

借助上述结论,来逐步分析多人情形。

当N=5人时,第一次先T1、T2两人过桥,T1把电筒送回,没过桥的又变成了T1、T3、T4、T5的4人情形。这个时候,需要比较T1+T4与2T3的大小吗?

第一种方案,还是选择T1来回送电筒,过桥总时间:为T2+T3+T1+T4+T1+T5

第二种方案,让慢的一起走,但因为送回电筒的不是T3,而是更快一点的T2,总过桥时间:T2+T5+T2+T3+T1+T2。

两种方案两者之差为T1+T4-2T2,这里与T3没有关系。

当N=6人时,第一次先T1、T2两人过桥,T1把电筒送回,没过桥的又变成了T1、T3、T4、T5、T6 的5人情形。按照刚才的分析,要比较T1+T5-2T2的大小。

以此类推,两种方案的差异,只与最快的人、次快的人和次慢的人的单独过桥时间有关,而与其他人的快慢无关。

例题:

题目描述:
有n个人过河,但是河边只有一艘船;船每次最多坐三个人,每个人单独坐船过河的时间为a[i],两个人或者三个人一起坐船时,过河时间为他们所有人中最长的过河时间;为安全起见,要求每次至少有俩个人才能过河。问最短需要多少时间,才能把所有人送过河。

解题思路
贪心算法:

  1. 两个人或三个人取时间最长的
  2. 四个人先最短的三个先过,前两个回来,带最后一个
  3. 4人以上,有两种情况时间最短:
    1)最短的两个带最长的,再回来带次最长的,依次带完
    2)最短的两个带第三短的,最短的两个回来,由最短的带最长的两个过去,第一短和第三短回来。这样每次都将最长的两个送到对岸。

代码如下:

def min_time(a,n):
    a.sort()
    min_val=0
    while n>=7:
        tmp=a[2]+a[1]+a[3]+a[1]+a[n-1]+a[3]
        min_val+=tmp
        n-=3
    if n>4 and n<=6:
        tmp=min((a[n-1]+a[1]+a[n-2]+a[2]),(a[2]+a[1]+a[n-1]+a[2]))
        min_val+=tmp
        n-=2
    if n==2 or n==3:
        min_val+=a[n-1]   
    if n==4:
        min_val+=a[2]+a[1]+a[3]
    return min_val

122. 买卖股票的最佳时机 II
给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格。

在每一天,你可能会决定购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以购买它,然后在 同一天 出售。
返回 你能获得的 最大 利润 。

输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        profit = 0
        for i in range(1, len(prices)):
            tmp = prices[i] - prices[i - 1]
            if tmp > 0: profit += tmp
        return profit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值