《程序员的算法趣题》-(日)增井敏克 Python解题 -- (Q28)

《程序员的算法趣题》-(日)增井敏克 , 书中为69 道数学谜题编写了解题程序, 编程语言为:Ruby(为主),JavaScript,C语言。有兴趣的同学,可以购书阅读~

在此更新个人编写的Python版,仅供学习使用。(运行环境:Python3.6)

Q28 社团活动的最优分配方案

    对学生而言,社团活动可能比学习还更重要。假设你即将成为某新建学校的校长,学校里有150 名想要运动的学生,请
你考虑要为他们准备哪些社团活动。
    你调查各项运动所需的场地面积后得到了如表所示的表格。在确定活动场地时,也要考虑各个社团的人数。

                                                 

问题
    请选择一些社团活动,社团总人数不能超过 150 人,还要使场地面积最大。求这个最大的面积的值。

分三种写法完成此题,各有优势。

group_info = [(11000, 40),
              (8000, 30),
              (400, 24),
              (800, 20),
              (900, 14),
              (1800, 16),
              (1000, 15),
              (7000, 40),
              (100, 10),
              (300, 12)]

    # 最简单,递归

MAX_AREA = 0
def calculate(res_group, people, area):
    for group in res_group:
        if group[1] + people > 150:
            global MAX_AREA
            MAX_AREA = max(MAX_AREA, area)
        else:
            new_res_group = res_group[:]
            new_res_group.remove(group)
            calculate(new_res_group, group[1]+people, area+group[0])

calculate(group_info, 0, 0)
print("最大的面积的值:%s" % MAX_AREA)

    # 动态加载

from copy import deepcopy
number_area = {0: 0}

for group in group_info:
    old_number_area = deepcopy(number_area)
    for number in old_number_area:
        new_number = number + group[1]
        new_area = old_number_area[number]+group[0]
        if new_number <= 150:
            if new_number in number_area:
                number_area[new_number] = max(old_number_area[new_number], new_area)
            else:
                number_area[new_number] = new_area

print("最大的面积的值:%s" % max(number_area.values()))

     # 内存化

calculated_map = {}
def calculate(res_people, res_group):
    if res_people < 0 or len(res_group) == 0:
        return 0
    elif (res_people, tuple(res_group)) in calculated_map:
        return calculated_map[(res_people, tuple(res_group))]

    max_area = 0
    for group in res_group:
        if group[1] <= res_people:
            new_res_group = res_group[:]
            new_res_group.remove(group)
            max_area = max(group[0] + calculate(res_people-group[1], new_res_group), max_area)

    calculated_map[(res_people, tuple(res_group))] = max_area

    return max_area

print("最大的面积的值:%s" % calculate(150, group_info))

运行结果:

           最大的面积的值:28800

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值