OD C卷 - 伐木工

伐木工(200)

  • 一根X米长的树木,切成不同长度(均为整数)的木材后进行交易,也可整根树木交易;
  • 交易的价格为每根木头段长度(即木头段最大价值)之积(如切割为a, b, c段,收益为abc),若未切割则收益为X*1;
  • 如何尽量少的切割,使收益最大化?
    输入描述:
    木材的长度X<=50
    输出描述:
    最优收益时,各个树木段的长度,升序排序,以空格分割

示例1
输入:
10
输出:
3 3 4
说明:
一根2米长的树木,不需要切割,最大收益为2;
一根4米长的树木,不需要切割,最大收益为4;
一根5米长的树木,切割为2,3,最大收益为6;
一根10米长的树木,切割为3,4,3,也可切为3,2,2,3,只不过同样的收益多切了一次,增加成本;

思路:

  • 贪心算法,大化小,大问题依赖小问题的最优解;
  • 根据题意可知,当树木长度为1、2、3、4 时,不用切割就可以获取最大价值,当树木长度更大时,依次从长度为1开始求最优解,例如长度从1 -> 10的树木各自的最大价值及分段可以表示为如下:
    • max_price [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],长度为 i 的树木可卖的最大价值为 i
    • pies = [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10]],长度为 i 的树木获取最大价值时的分段

其他方案:

 
# 树木的长度
total_len = int(input().strip())

# 默认的最大价值
max_price = [i for i in range(total_len + 1)]

# 长度为i的树木 在获取最大价值时的分段
pies = [[i] for i in range(total_len + 1)]  # i = 1,2,3,4 时 是不用分段的

# 从最小的问题开始求解,直到达到目标的大问题
i = 1
while i <= total_len:

	# 对当前长度为i的树木 进行分段
	for j in range(1, i): # j 为第一段, k 为另一段
		k = i - j
	    if max_price[i] > max_price[j] * max_price[k]: # 分段之积 j*k 实际上是max_price[j] * max_price[k]
	        continue
	    
	    # 更新最大价值
	    elif max_prce[i] < max_price[j] * max_price[k]:
	        max_price[i] = max_price[j] * max_price[k]
	        pies[i] = []
	        for a in range(len(pies[j])):
	            pies[i].append(pies[j][a])
	        for a in range(len(pies[k])):
	            pies[i].append(pies[k][a])
	    else: # 等价值时,取最少的分段
	        if len(pies[i]) > len(pies[j]) + len(pies[k]):
	            pies[i] = []
	            for a in range(len(pies[j])):
	                pies[i].append(pies[j][a])
	            for a in range(len(pies[k])):
	                pies[i].append(pies[k][a])
    i+=1
 
result = pies[total_len]
result.sort()
output_str = ""
for i in range(len(result)):
    output_str += str(result[i]) + " "
print(output_str)
    

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laufing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值