E-MELON的难题-200分

刷题笔记合集🔗

题目描述

MELON有一堆精美的雨花石(数量为n,重量各异),准备送给S和W。MELON希望送给两人的雨花石重量一致,请设计一个程序,帮MELON确认是否能将雨花石平均分配。

输入格式

第1行输入为雨花石个数n,其中0 < n < 31。 第2行输入为空格分割的各雨花石重量:m[0] m[1] ... m[n-1],其中0 < m[k] < 1001。

不需要考虑异常输入的情况。

输出格式

如果可以均分,输出从当前雨花石中最少需要拿出几块,可以使两堆的重量相等; 如果不能均分,则输出-1。

约束说明

  • 1 ≤ n ≤ 30
  • 1 ≤ m[k] ≤ 1000

样例输入1

4
1 1 2 2

样例输出1

2

样例说明1

输入第一行代表共4颗雨花石,第二行代表4颗雨花石重量分别为1、1、2、2。 均分时只能分别为1,2,需要拿出重量为1和2的两块雨花石,所以输出2。

样例输入2

10
1 1 1 1 1 9 8 3 7 10

样例输出2

3

样例说明2

输入第一行代表共10颗雨花石,第二行代表雨花石重量。 均分方案有多种:

  1. 1,1,1,1,1,9,7和10,8,3 (拿出3块)
  2. 1,1,1,1,9,8和10,7,3,1 (拿出4块)
  3. ...其他均分方式 第一种方案只需要拿出重量为10,8,3的3块雨花石,是最少的,所以输出3。

题目解析

本题是一个变种的01背包问题。关键点:

  1. 问题分析

    • 首先判断总重量是否能被2整除
    • 如果可以整除,则尝试找到最少数量的石头组成一半重量
    • 如果找不到这样的组合,说明无法平分
  2. 动态规划实现

    • dp[i][j]表示从前i个石头中选择,能装满重量j的最少石头数
    • 状态转移:dp[i][j] = min(dp[i-1][j], dp[i-1][j-w] + 1)
    • 初始化:dp[0][0]=0, dp[0][j]=n(j>0)
  3. 求解步骤

    • 计算总重量sum
    • 如果sum为奇数,返回-1
    • 否则目标重量为sum/2
    • 使用dp求解最少需要的石头数

时间复杂度: O(n*sum),其中n是石头数量,sum是总重量

参考代码

def solve():
    # 读取输入
    n = int(input())
    stones = list(map(int, input().split()))
    
    # 计算总重量
    total = sum(stones)
    if total % 2 != 0:
        return -1
        
    target = total // 2
    
    # dp[i][j]表示从前i个石头中选择,能装满重量j的最少石头数
    dp = [[n+1] * (target + 1) for _ in range(n + 1)]
    dp[0][0] = 0
    
    # 动态规划
    for i in range(1, n + 1):
        w = stones[i-1]
        for j in range(target + 1):
            if j < w:
                dp[i][j] = dp[i-1][j]
            else:
                dp[i][j] = min(dp[i-1][j], dp[i-1][j-w] + 1)
    
    # 如果无法达到目标重量
    if dp[n][target] == n+1:
        return -1
        
    return dp[n][target]

if __name__ == "__main__":
    print(solve())
#include 

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论

相关推荐

回首过去,考研这一站对我来说,既是一个重要的选择,也是一次深刻的成长。对于我来说,考研并不是唯一的出路,而放弃考研,选择直接进入职场,也让我走出了属于自己的精彩道路。考研路上的纠结与挣扎大学时,我一直有考研的打算。那时,考研似乎是许多同学的共同目标,身边的朋友们都在默默为考研努力着。于是,我也把大部分时间投入到备考中,准备过一次深入思考人生的考试。但是,随着备考的深入,我开始感到一些疑惑。虽然大家都说考研能带来更高的学历,打开更多的职业大门,但我逐渐发现自己更倾向于直接进入社会,积累实际工作经验。那段时间,经历了内心的挣扎和纠结:一方面,考研似乎是一个“安全”的选择,另一方面,职场的诱惑也在悄悄吸引我。放弃考研,全力以赴投入工作最终,我做出了决定——放弃考研,全力以赴投入工作。我认为,如果选择工作,我可以直接接触到真实的行业需求,面对实际的挑战,学习更多的技能和经验,这将比单纯的学术深造更加有意义。当时的决定并不容易,特别是身边的同学和老师都对考研充满期待和鼓励,我也曾有过动摇。但最终,我意识到,每个人的道路都是独一无二的,我不需要遵循别人设定的轨迹。我希望通过工作,在实际的环境中不断摸索和成长,为自己的职业生涯打下坚实的基础。工作中的成长与收获放弃考研后的职业选择让我有了更多的机会去接触不同的行业和岗位。我通过实践不断提升自己的技能,积累了丰富的项目经验。每当遇到挑战时,我都能快速学习并找到解决方案,这种从实际工作中汲取知识的方式让我感到非常充实。最重要的是,这段工作经历让我更加明确了自己的职业方向。我发现自己对技术开发特别感兴趣,决定继续在这条道路上深耕。通过不断努力和积累,我在公司获得了晋升机会,也逐渐确立了自己的职业目标。#考研人,我有话说#
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务