目录
问题 A: 放苹果
问题 B: XP的矩阵
问题 C: 最大子段和
问题 D: 补充能量
问题 F: 最大子段和升级版
题目描述
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?
(用K表示)5,1,1和1,5,1 是同一种分法。
输入
每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
输出
对输入的每组数据M和N,用一行输出相应的K。
while True:
try:
m, n = map(int, input().split())
dp = [[0] * (n + 1) for _ in range(m + 1)]
dp[0][0] = 1
for i in range(m + 1):
for j in range(1, n + 1):
dp[i][j] = dp[i][i] if i < j else dp[i][j - 1] + dp[i - j][j]
print(dp[m][n])
except:
break
题目描述
XP学长觉得矩阵很美,虽然他也不知道美在哪里,因此,他决定挖掘一下矩阵的美。现在给定一个m行n列的矩阵,从左上角开始每次只能向右或者向下移动,最后到达右下角的位置,将路径上的所有数字累加起来作为这条路径的路径和。XP学长决定编写一个程序来求所有路径和中的最小路径和。例如,下面矩阵中的路径1-3-1-0-6-1-0是所有路径中路径和最小的,返回结果是12。
1 3 5 9
8 1 3 4
5 0 6 1
8 8 4 0
输入
输入包含多组测试用例,第一行输入一个T表示测试数据组数,(1<=T<=15)
接下来有T组数据,每组先输入两个整数M,N接下来输入M*N的矩阵(1<=N,M<=1000),且最终结果在int范围内。
输出
输出路径和的最小值。
def computed(x: int, y: int):
if x == 0 and y == 0:
return
if x == 0:
maze[x][y] += maze[x][y - 1]
return
if y == 0:
maze[x][y] += maze[x - 1][y]
return
maze[x][y] += min(maze[x - 1][y], maze[x][y - 1])
return
t = int(input())
while t > 0:
t, maze = t - 1, []
m, n = map(int, input().split())
for _ in range(m):
maze.append([int(i) for i in input().split()])
# print(maze)
for i in range(m):
for j in range(n):
# print(maze[i][j])
computed(i, j)
# print(maze)
print(maze[m - 1][n - 1])
题目描述
给定n个整数(可能是负数)组成的序列a[1], a[2], a[3], …, a[n],求该序列的子段和如a[i]+a[i+1]+…+a[j]的最大值。
输入
每组输入包括两行,第一行为序列长度n,第二行为序列。
输出
输出字段和的最大值。
while True:
try:
n = int(input())
nums = [int(i) for i in input().split()]
for i in range(1, n):
nums[i] = max(nums[i - 1] + nums[i], nums[i])
# print(nums)
print(max(nums))
except:
break
题目描述
一年一度的宇宙超级运动会在宇宙奥特英雄体育场隆重举行。X星人为这场运动会准备了很长时间,他大显身手的时刻终于到了!
为了保持良好的竞技状态和充沛的体能,X星人准备了N个不同的能量包,每个能量包都有一个重量值和能量值。由于这些能量包的特殊性,必须要完整地使用一个能量包才能够发挥功效,否则将失去能量值。
考虑到竞赛的公平性,竞赛组委会规定每个人赛前补充的能量包的总重量不能超过W。
现在需要你编写一个程序计算出X星人能够拥有的最大能量值是多少?
输入
单组输入。
第1行包含两个正整数N和W,其中N<=103,W<=103。
第2行包含N个正整数,分别表示每一个能量包的重量,两两之间用空格隔开。
第3行包含N个正整数,分别表示每一个能量包的能量值,两两之间用空格隔开。
输出
输出X星人能够拥有的最大能量值。
n, w = map(int, input().split())
v, c, dp = [int(i) for i in input().split()], [int(i) for i in input().split()], [[0] * (w + 1) for _ in range(n + 1)]
# print(dp)
for i in range(1, n + 1):
for j in range(w + 1):
# print(i, j)
if v[i - 1] > j:
dp[i][j] = dp[i - 1][j]
else:
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i - 1]] + c[i - 1])
# print(dp)
print(dp[n][w])
题目描述
使用动态规划算法求整数数组(可能包含负整数)的最大子段和,以及和最大子段的起始位置和结束位置:
例如:输入数组(6,-1,5,4,-7),输出14, 1, 4,其中14表示最大子段和,1表示和最大的子段从第1个数字开始,4表示和最大的子段到第4个数字结束,即(6, -1 , 5, 4)。
输入
每组输入两行,第1行为数组中包含的整数个数n,第2行为n个整数(可能包含负整数),两两之间用空格隔开。
输出
输出最大子段和,以及和最大子段的起始位置和结束位置,两两之间用空格隔开。
while True:
try:
n = int(input())
nums = [int(i) for i in input().split()]
for i in range(1, n):
nums[i] = max(nums[i - 1] + nums[i], nums[i])
Max = max(nums)
index2, index1 = nums.index(Max) + 1, -1
for i in range(index2):
if nums[i] >= 0 and index1 == -1:
index1 = i + 1
elif nums[i] < 0:
index1 = -1
print(Max, index1, index2)
except:
break