鱼C论坛

 找回密码
 立即注册
查看: 5523|回复: 72

[已解决]Python:每日一题 265

[复制链接]
发表于 2019-10-28 20:37:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
今天的题目:


在 n 个物品中挑选若干物品装入背包,假设背包的大小为 m,每个物品的大小为 A[j](所有物品大小的列表为 A),最多能装多满?

示例 1:

输入:  m = 10, A = [3, 4, 8, 5]
输出:  9
示例 2:

输入:  m = 12, A = [2,3,5,7]
输出:  12


欢迎大家一起答题!
最佳答案
2019-10-30 16:47:40
  1. def fun265(self, m, A):
  2.       
  3.     A.sort(reverse=True)
  4.         
  5.     sizes=[]
  6.         
  7.     for i in range(len(A)):
  8.         size=0
  9.         B=A[i:]
  10.            
  11.         for j in range(len(B)):
  12.                
  13.             size+=B[j]
  14.             if size>m:
  15.                 size-=B[j]
  16.                 continue
  17.             
  18.         sizes.append(size)
  19.             
  20.     return max(sizes)
复制代码

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-28 21:03:29 | 显示全部楼层
来啦
  1. def solve(m, A):
  2.     n = len(A) - 1
  3.     def f(x, y):
  4.         if x == 0 or y == 0:
  5.             return 0
  6.         else:
  7.             a = f(x-1, y-A[x]) + A[x] if y >= A[x] else -1
  8.             b = f(x-1, y)
  9.             return max(a, b)
  10.     print(f(n, m))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-28 21:10:30 | 显示全部楼层


解答错误

输入:m = 90,A = [12,3,7,4,5,13,2,8,4,7,6,5,7]
输出:71
预期结果:83
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-28 21:19:58 | 显示全部楼层
不好意思 一点点错
  1. def solve(m, A):
  2.     n = len(A) - 1
  3.     def f(x, y):
  4.         if x == -1 or y == 0:
  5.             return 0
  6.         else:
  7.             a = f(x-1, y-A[x]) + A[x] if y >= A[x] else -1
  8.             b = f(x-1, y)
  9.             return max(a, b)
  10.     print(f(n, m))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-28 21:50:34 | 显示全部楼层
  1. import itertools

  2. def func(m,A):
  3.     A.sort
  4.     if A[0] > m:
  5.         return None
  6.     else:
  7.         list1 = []
  8.         for i in range(1,len(A)+1):
  9.             temp = itertools.combinations(A,i)
  10.             for each in temp:
  11.                 x = 0
  12.                 for j in each:
  13.                     x += j
  14.                 list1.append(x)
  15.         result = list1[0]
  16.         for each in list1:
  17.             if each <= m:
  18.                 if m - each < m - result:
  19.                     result = each
  20.         return result
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-28 22:13:37 | 显示全部楼层
Unicorn# 发表于 2019-10-28 21:19
不好意思 一点点错


输入 m = 5000,A = [828,125,740,724,983,321,773,678,841,842,875,377,674,144,340,467,625,916,463,922,255,662,692,123,778,766,254,559,480,483,904,60,305,966,872,935,626,691,832,998,508,657,215,162,858,179,869,674,452,158,520,138,847,452,764,995,600,568,92,496,533,404,186,345,304,420,181,73,547,281,374,376,454,438,553,929,140,298,451,674,91,531,685,862,446,262,477,573,627,624,814,103,294,388] 超时
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-28 22:15:00 | 显示全部楼层

A.sort()

帮你改正了

输入 m = 5000,A = [828,125,740,724,983,321,773,678,841,842,875,377,674,144,340,467,625,916,463,922,255,662,692,123,778,766,254,559,480,483,904,60,305,966,872,935,626,691,832,998,508,657,215,162,858,179,869,674,452,158,520,138,847,452,764,995,600,568,92,496,533,404,186,345,304,420,181,73,547,281,374,376,454,438,553,929,140,298,451,674,91,531,685,862,446,262,477,573,627,624,814,103,294,388] 超出内存限制
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-28 23:08:45 | 显示全部楼层
  1. from itertools import combinations

  2. def max_load(size,goods):
  3.     # 求物品的组合情况
  4.     con_goods = goods.copy()
  5.     for i in range(2,len(goods)+1):
  6.         goods_new = map(sum,combinations(goods,i))
  7.         con_goods.extend(goods_new)

  8.     # 取最大装载数
  9.     while True:
  10.         if size in con_goods:
  11.             return size
  12.         else:
  13.             size -= 1

  14. print(max_load(12,[2,3,5,7]))
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 00:48:37 | 显示全部楼层
zltzlt 发表于 2019-10-28 22:13
输入 m = 5000,A = [828,125,740,724,983,321,773,678,841,842,875,377,674,144,340,467,625,916,463, ...

DP都会超时.....难搞
我再优化试试
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 01:00:33 | 显示全部楼层
zltzlt 发表于 2019-10-28 22:13
输入 m = 5000,A = [828,125,740,724,983,321,773,678,841,842,875,377,674,144,340,467,625,916,463, ...

添加了记忆化搜索,的确快很多了
递归重复次数太多了
是个狠人
  1. def solve(m, A):
  2.     n = len(A) - 1
  3.     record = {}
  4.     def f(x, y):
  5.         if (x, y) in record:
  6.             return record[(x, y)]
  7.         elif x == -1 or y == 0:
  8.             record[(x, y)] = 0
  9.             return 0
  10.         else:
  11.             if y >= A[x]:
  12.                 a = f(x-1, y-A[x]) + A[x]
  13.             else:
  14.                 a = -1
  15.             b = f(x-1, y)
  16.             t = max(a, b)
  17.             record[(x, y)] = t
  18.             return t
  19.     print(f(n, m))
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 04:00:11 | 显示全部楼层
  1. class Backpack:

  2.     def calc(self, m, A):
  3.         p = [[0 for _ in range(m+1)] for _ in range(len(A))]

  4.         for i in range(len(A)):
  5.             for j in range(m, 0, -1):
  6.                 if i == 0:
  7.                     if j >= A[i]:
  8.                         p[i][j] = p[i][j-A[i]] + A[i]
  9.                 elif j >= A[i]:
  10.                     p[i][j] = p[i-1][j-A[i]] + A[i]
  11.                 else:
  12.                     p[i][j] = max(p[i][j],p[i-1][j])

  13.         return p[len(A)-1][m]

  14. if __name__ == '__main__':

  15.     bp = Backpack()
  16.     m, A = 90, [12,3,7,4,5,13,2,8,4,7,6,5,7]
  17.    
  18.     result = bp.calc(m, A)
  19.     print(result)
复制代码

评分

参与人数 1贡献 +1 收起 理由
zltzlt + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 06:39:55 | 显示全部楼层
本帖最后由 Stubborn 于 2019-10-29 07:25 编辑

时间有点超,先睡觉,起床再优化吧,结果验算了下,结果没有问题,楼上可能就问题了,顺便看看,是哪里的耗时了
  1. m, A = 5000, [828,125,740,724,983,321,773,678,841,842,875,377,674,144,340,467,625,916,463,922,255,662,692,123,778,766,254,559,480,483,904,60,305,966,872,935,626,691,832,998,508,657,215,162,858,179,869,674,452,158,520,138,847,452,764,995,600,568,92,496,533,404,186,345,304,420,181,73,547,281,374,376,454,438,553,929,140,298,451,674,91,531,685,862,446,262,477,573,627,624,814,103,294,388]

  2. import copy
  3. def solve(m, A):

  4.     result = set()

  5.     S_dict = {}
  6.     for a, b in enumerate(A):
  7.         S_dict[m - b] = [a,]

  8.     def _n(m:int, value:list):
  9.         for a,b in enumerate(A):
  10.             if a in value:
  11.                 continue
  12.             if m - b >= 0:
  13.                 var = copy.copy(value)
  14.                 var.append(a)
  15.                 try:
  16.                     result.add(m-b)
  17.                     S_dict[m-b] = S_dict.pop(m)
  18.                 except KeyError:
  19.                     S_dict[m - b] = var
  20.                     continue
  21.                 S_dict[m-b] = var

  22.         return copy.copy(S_dict)

  23.     a = len(A)
  24.     for _ in range(a):
  25.         s = copy.copy(S_dict)
  26.         for key,value in s.items():
  27.             _n(key, value)
  28.     return m - min(result), S_dict.get(0, None)

  29. print(solve(m,A))

  30. (5000, [91, 80, 31, 67, 1, 58, 23, 51, 13, 49, 45, 92, 76, 43, 66, 85, 62, 26, 20, 42, 5, 32, 63, 77, 59])
复制代码


###################################有毒,躺下思索下,觉得很多地方不用判,下面是修改版,基本是秒出了###############################
  1. import copy
  2. def solve(m, A):

  3.     A.sort()
  4.     result,index =set(),0
  5.     min_A = min(A)



  6.     S_dict = {}
  7.     for a, b in enumerate(A):
  8.         S_dict[m - b] = [a,]

  9.     def _n(m:int, value:list):
  10.         for a,b in enumerate(A):
  11.             if m < min_A or m - b < 0:
  12.                 break
  13.             elif a in value:
  14.                 continue
  15.             elif m - b > 0:
  16.                 var = copy.copy(value)
  17.                 var.append(a)
  18.                 try:
  19.                     result.add(m-b)
  20.                     S_dict[m-b] = S_dict.pop(m)
  21.                 except KeyError:
  22.                     pass
  23.                 S_dict[m-b] = var
  24.             else:
  25.                 return True

  26.     a = len(A)
  27.     for _ in range(a):
  28.         s = copy.copy(S_dict)
  29.         for key,value in s.items():
  30.             if _n(key,value):
  31.                 return m
  32.     return m - min(result), S_dict.get(min(result), None)
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 08:31:47 | 显示全部楼层
  1. from itertools import combinations


  2. def kao(val, lst):
  3.     lst.sort()
  4.     l = []
  5.     if lst[0] > val:
  6.         return False
  7.     for i in range(2, len(lst) + 1):
  8.         for j in combinations(lst, i):
  9.             l.append(sum(j))
  10.     if val in l:
  11.         return val
  12.     else:
  13.         return Search(list(set(l)), val)


  14. def Search(lst, val):
  15.     lst.sort()
  16.     low = 0
  17.     height = len(lst)
  18.     while low < height:
  19.         mid = int((low + height) / 2)
  20.         if lst[mid] < val:
  21.             low = mid + 1
  22.         elif lst[mid] > val:
  23.             return lst[mid - 1]


  24. print(kao(16, [2, 3, 5, 7]))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 08:58:25 | 显示全部楼层
  1. def f265(m, A):
  2.     lst, tmp_lst = [0] * (m + 1), [0] * (m + 1)
  3.     for raw in range(len(A)):
  4.         for col in range(1, m+1):
  5.             if col < A[raw]:
  6.                 tmp_lst[col] = lst[col]
  7.             else:
  8.                 tmp_lst[col] = max(lst[col-A[raw]] + A[raw], lst[col-A[raw]])
  9.         lst = tmp_lst[:]

  10.     return lst[-1]
复制代码

评分

参与人数 1贡献 +1 收起 理由
zltzlt + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 09:06:54 | 显示全部楼层
我写了个有局限性的函数,但目前没发现能让它出错的输入数据,所以我就发出来了:
  1. def load(m:int,A:'list')->int:
  2.     tot = 0
  3.     A.sort(reverse=True)#确定从大到小的顺序
  4.     length = len(A)
  5.     for i in range(length):#左边界渐渐向右逼近
  6.         sums = 0
  7.         for j in A[i:]:
  8.             sums += j
  9.             if sums == m:#背包能够被装满,直接输出背包容量
  10.                 return m
  11.             elif m > sums > tot:#在不超过背包容量的前提下,尽可能的装载
  12.                 tot = sums
  13.             elif sums > m:#装了这个大件就超过了容量,所以不装
  14.                 sums -= j
  15.         if sums < tot:#无法再创新高
  16.             break
  17.     return tot

  18. if __name__ == '__main__':
  19.     print('示例1 输出:',load(10,[3,4,8,5]))
  20.     print('示例2 输出:',load(12,[2,3,5,7]))
  21.     print('大数据?输出:',load(m = 5000, A = [828,125,740,724,983,321,773,678,841,842,875,377,674,144,340,467,625,916,463,922,255,662,692,123,778,766,254,559,480,483,904,60,305,966,872,935,626,691,832,998,508,657,215,162,858,179,869,674,452,158,520,138,847,452,764,995,600,568,92,496,533,404,186,345,304,420,181,73,547,281,374,376,454,438,553,929,140,298,451,674,91,531,685,862,446,262,477,573,627,624,814,103,294,388]))
复制代码

因为我自己不是很确定,所以稍微改了改,让输出包含了最多能装的、和怎么装能装这么多
  1. def load(m:int,A:'list')->tuple:
  2.     tot = 0
  3.     who = []
  4.     A.sort(reverse=True)#确定从大到小的顺序
  5.     length = len(A)
  6.     for i in range(length):#左边界渐渐向右逼近
  7.         sums = 0
  8.         adds = []
  9.         for j in A[i:]:
  10.             sums += j
  11.             adds.append(j)
  12.             if sums == m:#背包能够被装满,直接输出背包容量
  13.                 return (m,adds)
  14.             elif m > sums > tot:#在不超过背包容量的前提下,尽可能的装载
  15.                 tot = sums
  16.                 who = adds
  17.             elif sums > m:#装了这个大件就超过了容量,所以不装
  18.                 sums -= j
  19.                 adds.pop()
  20.         if sums < tot:#无法再创新高
  21.             break
  22.     return (tot,who)

  23. if __name__ == '__main__':
  24.     print('示例1 输出:',load(10,[3,4,8,5]))
  25.     print('示例2 输出:',load(12,[2,3,5,7]))
  26.     print('大数据?输出:',load(m = 5000, A = [828,125,740,724,983,321,773,678,841,842,875,377,674,144,340,467,625,916,463,922,255,662,692,123,778,766,254,559,480,483,904,60,305,966,872,935,626,691,832,998,508,657,215,162,858,179,869,674,452,158,520,138,847,452,764,995,600,568,92,496,533,404,186,345,304,420,181,73,547,281,374,376,454,438,553,929,140,298,451,674,91,531,685,862,446,262,477,573,627,624,814,103,294,388]))
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2019-10-29 14:26:53 | 显示全部楼层
def solution(m:int, A: list) -> int :
    A.sort()
    res = set()
    s = 0
    dfs(m, A, res, s)
    return max(res)

def dfs(m:int, A:list, res:set, s:int):
    if not A:
        res.add(s)
        return
    for i,v in enumerate(A):
        if v>m:
            res.add(s)
            return
        else:
            dfs(m-v, A[i+1:],res,s+v)
应该会超时...后面用dp改下

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 15:02:08 | 显示全部楼层
  1. def package(A,m):
  2.     res=0
  3.     for j in range(2**len(A)):
  4.         tmp = j
  5.         total=0
  6.         count=0
  7.         while tmp!=0:
  8.             total+=A[count]*(tmp%2)
  9.             tmp=tmp//2
  10.             count+=1
  11.         if m>=total >res:
  12.             res=total
  13.     return res
复制代码

评分

参与人数 1贡献 +1 收起 理由
zltzlt + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 16:33:01 | 显示全部楼层
本帖最后由 Stubborn 于 2019-10-29 17:03 编辑
阴阳神万物主 发表于 2019-10-29 09:06
我写了个有局限性的函数,但目前没发现能让它出错的输入数据,所以我就发出来了:

因为我自己不是很确定 ...


不知道是不是我验算有问题还是啥
  1. m, A = 10000, [828, 125, 740, 724, {:10_266:}983, 321, 773, 678, 841, 842, 875, 377, 674, 144, 340, 467, 625, 916, 463, 922, 255,
  2.                662, 692, 123, 778, 766, 254, 559, 480, 483, 904, 60, 305, 966, 872, 935, 626, 691, 832, 998, 508, 657,
  3.                215, 162, 858, 179, 869, 674, 452, 158, 520, 138, 847, 452, 764, 995, 600, 568, 92, 496, 533, 404, 186,
  4.                345, 304, 420, 181, 73, 547, 281, 374, 376, 454, 438, 553, 929, 140, 298, 451, 674, 91, 531, 685, 862,
  5.                446, 262, 477, 573, 627, 624, 814, 103, 294, 388] * 2


  6. (9997, [995, 983, 983, 966, 966, 935, 935, 929, 929, 922, 454])

  7. 我运算,就是速度台太行了:(10000,[998, 995, 995, 983, 983, 966, 966, 935, 929, 321, 929])

  8. A = 20000, m = m * 5

  9. (19992, [998, 998, 998, 998, 995, 995, 995, 995, 995, 983, 983, 983, 983, 983, 966, 966, 966, 966, 966, 935, 345])

  10. 我运算,就是速度台太行了:(20000,[998, 998, 998, 998, 995, 995, 995, 995, 995, 983, 983, 983, 983, 983, 966, 966, 966, 966, 998, 321, 935])
复制代码


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 17:36:17 | 显示全部楼层
  1. def function(m:int, a:list):
  2.     a.sort(reverse=True)
  3.     res = 0
  4.     for i in range(len(a)):
  5.         add = a[i]
  6.         b = a[i+1:]
  7.         while add <= m:
  8.             for j in range(len(b)):
  9.                 if b[j] <= m - add:
  10.                     add += b[j]
  11.                     b = b[j+1:]
  12.                     break
  13.             else:
  14.                 break
  15.         #print(add)
  16.         if add > res:
  17.             res = add
  18.     return res
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-29 18:08:18 | 显示全部楼层
本帖最后由 阴阳神万物主 于 2019-10-29 18:20 编辑
Stubborn 发表于 2019-10-29 16:33
不知道是不是我验算有问题还是啥


所以,这种的就是我的代码的局限所在。我等会儿再改。
话说, 12. 行那里是不是漏了个滑稽?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-7 18:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表