作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我要解决的问题是,假设您有一个每列中的树数列表,例如[10,20,10,0],这个列表中的每个元素是该列中存在的树的数量,意味着在第一列中有十棵树,在第二列中有 20 棵树,依此类推。列数是固定的,切掉一列,其列数将变为零。如果可能的话,你可以完全砍掉一行或一列,但你只能砍掉连续的行或列,这意味着如果你有 [4,0,4] 你不能为了砍掉所有的树而砍掉行。对于 [4,0,4] 只需要两次尝试,减少第一列和第三列。我会给你另一个例子,假设你有一个 [4,3,4,3,4] 的列表,你可以减少三行并使其成为 [1,0,1,0,1] 但是你必须删除总共需要 6 个步骤的三列,但您也可以减少所有需要 5 个步骤的列,任何其他解决方案的结果都会大于 5 个步骤。
编辑:这张图片将澄清问题:首先,您剪切具有 4 个元素的列,然后剪切第一行,然后剪切现在具有 2 个元素的列,然后剪切最后一行或最后一列。正如我之前所说,您不能剪切不连续的行。 (一行中出现的所有元素都应该相邻,以便能够减少该行)(在这张图片中,第 3 行有一个不连续点) enter image description here
我已经尝试解决这个问题两天了,我一无所获。我的最新代码在这里,它进入非正方形的几乎无限循环,例如 [例如 3 的列表,最多元素为 200] 树列表。
def cut_tree_row(tree):
res = []
discontinoue_flag = 0 # A flag to findout if cutting down the row is possible or not
non_zero_flag_once = 0 # if the program encounters a non_zero element for the first time this would change to 1
non_zero_flag_twice = 0# if the program encounters a non_zero element for the second time while the discontinue flag is 1, it would change to 1
for i in xrange(len(tree)):
if tree[i] > 0:
non_zero_flag_once = 1
if non_zero_flag_once == 1 and discontinoue_flag == 1:
non_zero_flag_twice = 1
else:
res.append(tree[i]-1)
else:
if discontinoue_flag == 0 and non_zero_flag_once == 1:
discontinoue_flag = 1
if discontinoue_flag == 1 and non_zero_flag_twice == 1:
return [], 10000000
res.append(0)
if discontinoue_flag == 1 and non_zero_flag_twice == 1:
return [], 10000000
return res , 1
def cut_tree_column(tree):
res = []
max_index = 0
m = max(tree)
flag = 1
if len(tree) == 0:
return tree , 0
for i in xrange(len(tree)):
if tree[i] == m and flag == 1:
flag = 0
res.append(0)
continue
res.append(tree[i])
return res , 1
def find_min_attempts(tree, total_sum = 0):
if len(tree) == 0:
return total_sum
s = sum(tree)
if s == 0:
return total_sum
res1 , num1 = cut_tree_column(tree)
res2 , num2 = cut_tree_row(tree)
return min(find_min_attempts(res1, total_sum + num1),find_min_attempts(res2, total_sum + num2))
def main():
tree = [187, 264, 298, 924, 319] #This input gives me an infinite loop
print find_min_attempts(tree)
main()
最佳答案
此递归解决方案计算切割最大列和最大行后的步数。它返回两者中的最小值。
如果存在零,它将每个不连续的部分作为子问题求解。
def get_max_col(t):
""" Get index of tallest column """
return max(enumerate(t),key=lambda x: x[1])[0]
def remove_max_col(t):
""" Remove tallest column """
idx = get_max_col(t)
new_t = t[:]
new_t[idx] = 0
return new_t
def remove_bottom_row(t):
""" Remove bottom row """
return [x - 1 for x in t]
def splitz(iterable, val):
""" Split a list using val as the delimiter value """
result = []
group = []
for e in iterable:
if e == val:
if group: # ignore empty groups
result.append(group)
group = [] # start new
else:
group.append(e)
if group: # last group
result.append(group)
return result
def min_cuts(t):
# All zeroes, finished
if set(t) == set([0]):
return 0
# Single column
if len(t) == 1:
return 1
# All ones, single row
if set(t) == set([1]):
return 1
# If discontinued, add cost of subproblems
if 0 in t:
sub_ts = splitz(t, 0)
return sum(map(min_cuts, sub_ts))
# try removing the largest column and largest row(bottom)
# Pick the cheapest one
else:
t1 = remove_max_col(t)
x = 1 + min_cuts(t1)
t2 = remove_bottom_row(t)
y = 1 + min_cuts(t2)
return min(x, y)
print(min_cuts([4,3,4,3,4]))
print(min_cuts([187, 264, 298, 924, 319]))
关于python - 给定一个树高列表,找到尽可能少的尝试将它们砍倒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47374607/
我是一名优秀的程序员,十分优秀!