HNUCM-2022年秋季学期《算法分析与设计》练习10

目录

问题 A: 放苹果

问题 B: XP的矩阵

问题 C: 最大子段和

问题 D: 补充能量

问题 F: 最大子段和升级版


问题 A: 放苹果

题目描述

把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

问题 B: XP的矩阵

题目描述

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])

问题 C: 最大子段和

题目描述

给定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

问题 D: 补充能量

题目描述

一年一度的宇宙超级运动会在宇宙奥特英雄体育场隆重举行。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])

问题 F: 最大子段和升级版

题目描述

使用动态规划算法求整数数组(可能包含负整数)的最大子段和,以及和最大子段的起始位置和结束位置:
例如:输入数组(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

你可能感兴趣的:(算法分析与设计,算法)