zoukankan      html  css  js  c++  java
  • 数据结构与算法11:贪心算法

    贪心算法介绍:

      对问题求解时,总是做出在当前看来最好的选择

      基本思路:

        建立数学模型来描述问题

        把求解的问题分成若干个子问题

        对每一个子问题求解,得到子问题的局部最优解

        把子问题的解局部最优解合成原来解问题的一个解

      贪心策略适用的前提:局部足有策略能导致产生全局最优解。

      贪心算法与动态规划算法的主要区别:

        动态规划算法通常是自底向上的方式求解子问题,而贪心算法则通过自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心的选择就所求问题简化为规模更小的子问题。

      问题描述1:找硬币:

        设有n中不同的硬币,现要用这些面值的硬币来找钱,可以使用各种面值的硬币面值{1,2,5,10,20,50,100,500,1000},对任意钱数,设计一个用最少硬币找钱的方法。

    def FindClion(V):
        aviable = [1,2,5,10,20,50,100,200,500,1000]
        result = []
        for i in aviable[::-1]:
            while(V >= i):
                V -= i
                result.append(i)
        return result
    V = 98
    print(FindClion(V))

      问题描述2:活动问题

        N个活动,每个活动的开始时间为si,结束时间是fi。如果si>=fj or sj>=fi 则定义两场活动并不冲突。试着找到一种能够找到最多的非冲突活动的集合(S)。也就是无法找到集合S’,使得|S'|>|S|.

        S = 1 3 0 5 8 5

        F = 2 4 6 7 9 9 

    def printMaxActivities(acts):
        n = len(acts)
        sort_acts = sorted(acts,key=lambda tup:tup[1])
        pre = sort_acts[0]
        print(pre)
        for curr in sort_acts:
            if curr[0] >= pre[1]:
                print(curr)
                pre = curr
    
    acts = [(0, 6), (3, 6), (1, 2), (5, 7), (8, 9), (5, 9)]
    printMaxActivities(acts)

      问题描述3:

        如何找到一个最小的数字,数字的位数与数字位数之和给予:

        例如: Input: s = 9, m = 2

           output:18

    def FindSmallest(m , s):
        if s == 0:
            if m == 1:
                print("Smallest number is 0")
            else:
                print("Not possible")
            return
        if s > m * 9:
            return
        result = [0 for i in range(m+1)]
        s -= 1
        for i in range(m-1, 0, -1):
            if s <= 9:
                result[i] = s
                s = 0
            else:
                result[i] = 9
                s -= 9
    
        result[0] = s + 1
        for i in range(m):
            print(result[i], end="")
    
    s = 20
    m = 3
    FindSmallest(m, s)

      问题描述4:

        将一个数组拆分为两个数字,求两个数字的和最小

        例 Input:[6 8 4 5 2 3] Output:604 The minimum sum is formed by numbers 358 and 246

    import heapq
    def minSum(a):
        heapq.heapify(a)
        num1 = 0
        num2 = 0
        while(a):
            num1  = num1 * 10 + heapq.heappop(a)
            if a:
                num2 = num2 * 10 + heapq.heappop(a)
        return num1 + num2
    a = [6, 8, 4, 5, 2, 3]
    print(minSum(a))

      问题描述5:

        以最小成本去连接一些绳子。

    import heapq
    def ropeCost(ropes):
        if len(ropes) == 1:
            return 0
        heapq.heapify(ropes)
        total = 0
        while ropes:
            first = heapq.heappop(ropes)
            second = heapq.heappop(ropes)
            local = first + second
            total += local
            if not ropes:
                break
            heapq.heappush(ropes, local)
        return total
    ropes = [4, 3, 2, 6]
    print(ropeCost(ropes))

        

  • 相关阅读:
    【SQL跟踪工具】SQL Profiler 跟踪器
    使用Fiddler调试手机端页面请求/抓包
    SQL 常用判断语句
    VS中常用快捷键
    博客园博客自动生成目录/目录索引
    BZOJ 1135 P3488 LYZ-Ice Skates 线段树+Hall
    BZOJ 4823 老C的方块
    POJ
    BZOJ 1299 [LLH邀请赛]巧克力棒
    BZOJ 2437 [Noi2011]兔兔与蛋蛋
  • 原文地址:https://www.cnblogs.com/lvxiaoning/p/12044619.html
Copyright © 2011-2022 走看看