📅  最后修改于: 2023-12-03 15:37:15.232000             🧑  作者: Mango
这是一个关于国际空间研究组织(ISRO)的编程问题,出现在2015年ISRO计算机科学考试中。
一个1xn的棋盘被分成了一些大小为1x1或2x1的小块。在每个小块中都写有权值。现在要选择一些小块,使得它们的和最大,但是不能选择相邻的块。输出最大和以及被选择的块的数量。
2
3
1 2 3
4
4 5 6 7
4 2
12 3
这是一个经典的动态规划问题。我们可以用一个长度为n的dp数组来表示前i个小块的最大权值和,并且这些小块必选第i个小块。
对于第i个小块,有两种选择:选或者不选。如果选第i个小块,则前i-2个小块都不能选;如果不选第i个小块,则前i-1个小块中最大的权值和即为前i个小块中最大的权值和。所以状态转移方程为:
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
当i=0或1时,dp[i]的值即为nums[i]。
最终,dp[n-1]即为最大权值和。
通过这个方法,我们只需要O(n)的时间复杂度就能求得最大权值和及其选择的小块数量。
def max_weight(nums):
n = len(nums)
if n == 1:
return nums[0], 1
dp = [0] * n
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i in range(2, n):
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
count = 0
i = n-1
while i >= 0:
if dp[i] == dp[i-1]:
i -= 1
else:
count += 1
i -= 2
return dp[n-1], count
t = int(input())
for _ in range(t):
n = int(input())
nums = list(map(int, input().split()))
result, count = max_weight(nums)
print(result, count)
以上是一个Python实现的代码。该代码可以通过测试数据,并且时间复杂度为O(n)。