【Py/Java/C++三种语言OD2023C卷真题】20天拿下华为OD笔试之【DP】2023C-分月饼【欧弟算法】全网注释最详细分类最全的华为OD真题题解

news2026/4/2 16:30:04

文章目录

  • 题目描述与示例
    • 题目描述
    • 输入描述
    • 输出描述
    • 示例
      • 输入
      • 输出
      • 说明
  • 解题思路
  • 代码
    • Python
    • Java
    • C++
    • 时空复杂度
  • 华为OD算法/大厂面试高频题算法练习冲刺训练

题目描述与示例

题目描述

中秋节,公司分月饼,m个员工,买了n个月饼,m <= n,每个员工至少分1个月饼,但可以分多个,单人分到最多月饼的个数是Max1,单人分到第二多月饼个数是Max2Max1-Max2 <= 3,单人分到第n-1多月饼个数是Max(n-1),单人分到第n多月饼个数是Max(n)Max(n-1)- Max(n) <= 3,问有多少种分月饼的方法?

输入描述

每一行输入m n,表示m个员工,n个月饼,m<=n

输出描述

输出有多少种月饼分法

示例

输入

2 4

输出

2

说明

分法有2种:

4=1+3
4=2+2

注意: 1+33+1算一种分法

解题思路

用比较严谨的数学语言表达上述问题为:挑选出m非递减的数,要求相邻两个数的差值不超过3,这m个数的和为n,问一共有多少种挑选方式。

由于在挑选完第i个数之后,第i+1个数的取值和第i个数的取值相关,很容易想到用动态规划来解决上述问题。思考动态规划三部曲:

  1. dp数组的含义是什么?

我们需要考虑三个因素,选择了第几个数,这个数取了什么数值,当前总和为多少。因此需要构建一个三维的dp数组。

考虑dp[i][j][k]表示,第i个数取值为j时,前i个数的总和为k的方法数。

分别考虑ijk三个数的取值范围来确定dp数组的大小。

ik的定义比较明确,范围分别是[1, m][1, n]

每个数字的取值j的最小为1,最大的情况为m-1个数字都选择最小数1,剩余一个最大数选择n-(m-1) = n-m+1。故j的取值范围是[1, n+m+1]

故构建dp数组是一个大小为(m+1)*(n-m+2)*(n+1)的三维数组。

  1. 动态转移方程是什么?

假设第i个数的取值为j,那么第i+1个数只能在jj+1j+2j+3中进行挑选。

若此时前i个数的总和为k,那么当第i+1个数

  • 取了j时,前i+1个数的总和为k+j。存在dp[i+1][j][k+j] += dp[i][j][k]
  • 取了j+1时,前i+1个数的总和为k+j+1。存在dp[i+1][j+1][k+j+1] += dp[i][j][k]
  • 取了j+2时,前i+1个数的总和为k+j+2。存在dp[i+1][j+2][k+j+2] += dp[i][j][k]
  • 取了j+3时,前i+1个数的总和为k+j+3。存在dp[i+1][j+3][k+j+3] += dp[i][j][k]

上述四个式子可以合并为一个式子,即dp[i+1][j+d][k+j+d] += dp[i][j][k],其中d的取值为[0,3]

先从小到大遍历i,再从小到大遍历j,再从小到大遍历k,则代码如下

for i in range(1, m):
    for j in range(1, n-m+2):
        for k in range(i, n+1):
            for d in range(4):
                if j+d < n-m+2 and k+j+d < n+1:
                    dp[i+1][j+d][k+j+d] += dp[i][j][k]
  1. dp数组如何初始化?

i = 0没有实际意义,不考虑。

考虑i = 1的情况,第1个数字的取值j最小为1,最大为n // m(即所有数字尽可能接近的情况),即此时j的取值为[1, n // m]

同时,由于只选择了一个数字,因此此时前i个数字的总和k = j

故对于i = 1,做如下初始化

dp = [[[0] * (n+1) for j in range(n-m+2)] for i in range(m+1)]
for j in range(1, n//m+1):
    dp[1][j][j] = 1

dp[1][j][j] = 1表示只对应1种方法数。

代码

Python

# 题目:【DP】2023C-分月饼
# 分值:200
# 作者:许老师-闭着眼睛学数理化
# 算法:DP
# 代码看不懂的地方,请直接在群上提问


# 输入员工人数m,月饼总数n
m, n = map(int, input().split())

# dp数组是一个大小为(m+1)*(n-m+2)*(n+1)的三维数组
# dp[i][j][k]表示,第i个数取值为j时,前i个数的总和为k的方法数
dp = [[[0] * (n+1) for j in range(n-m+2)] for i in range(m+1)]
# 第1个数字选了j,此时总和为j
# j的取值范围是[1, n//m]
# 因为m个数的和需要为n,那么最小那个数的最大值是n//m
for j in range(1, n//m+1):
    dp[1][j][j] = 1

# i的最大取值为m-1
for i in range(1, m):
    # j的最小取值为1,最大取值为n-m+1
    for j in range(1, n-m+2):
        # k的最小取值为i(前i个数都选了1,和为i),最大取值为n
        for k in range(i, n+1):
            # 增量d的取值范围为0,1,2,3
            for d in range(4):
                # 条件为j+d和k+j+d都没有超过对应的最大范围
                if j+d < n-m+2 and k+j+d < n+1:
                    dp[i+1][j+d][k+j+d] += dp[i][j][k]

ans = 0
# dp[m][j][n]表示第m个数(最后一个数)选了j后,总和为n的方法数
# 将所有的dp[m][j][n]加在一起即为答案
for j in range(n-m+2):
    ans += dp[m][j][n]

print(ans)

Java

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int m = scanner.nextInt();
        int n = scanner.nextInt();

        // dp array initialization
        int[][][] dp = new int[m + 1][n - m + 2][n + 1];
        for (int j = 1; j <= n / m; j++) {
            dp[1][j][j] = 1;
        }

        for (int i = 1; i < m; i++) {
            for (int j = 1; j <= n - m + 1; j++) {
                for (int k = i; k <= n; k++) {
                    for (int d = 0; d < 4; d++) {
                        if (j + d < n - m + 2 && k + j + d <= n) {
                            dp[i + 1][j + d][k + j + d] += dp[i][j][k];
                        }
                    }
                }
            }
        }

        int ans = 0;
        for (int j = 1; j <= n - m + 1; j++) {
            ans += dp[m][j][n];
        }

        System.out.println(ans);
    }
}

C++

#include <iostream>
using namespace std;

int main() {
    int m, n;
    cin >> m >> n;

    // dp array initialization
    int dp[m + 1][n - m + 2][n + 1] = {0};
    for (int j = 1; j <= n / m; j++) {
        dp[1][j][j] = 1;
    }

    for (int i = 1; i < m; i++) {
        for (int j = 1; j <= n - m + 1; j++) {
            for (int k = i; k <= n; k++) {
                for (int d = 0; d < 4; d++) {
                    if (j + d < n - m + 2 && k + j + d <= n) {
                        dp[i + 1][j + d][k + j + d] += dp[i][j][k];
                    }
                }
            }
        }
    }

    int ans = 0;
    for (int j = 1; j <= n - m + 1; j++) {
        ans += dp[m][j][n];
    }

    cout << ans << endl;

    return 0;
}

时空复杂度

时间复杂度:O(NM(N-M))。三重循环所需时间复杂度。

空间复杂度:O(NM(N-M))。三维dp数组所需空间。


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1389547.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ICCV2023 | VL-Match: 使用Token-Level和Instance-Level Matching提升视觉语言预训练

论文标题&#xff1a;VL-Match: Enhancing Vision-Language Pretraining with Token-Level and Instance-Level Matching 代码&#xff1a;None 单位&#xff1a;中国科学院北京计算技术研究所 中国科学院大学 微软 在VLP种&#xff0c;通常采用两种预训练任务&#xff0…

IF=16.6 | Quick CTL细胞免疫佐剂免疫HLA转基因小鼠,助力TCR- T细胞构建!

023年10月12日&#xff0c;中国科学院微生物研究所高福研究团队和谭曙光研究团队于Nature Communications发表了题为KRAS G12V neoantigen specific T cell receptor for adoptive T cell therapy against tumors的研究论文。 影响因子&#xff1a;16.6 Doi&#xff1a;KRAS G…

免费scrum管理工具Leangoo敏捷做缺陷跟踪管理

缺陷管理通常关注如下几个方面&#xff1a; 1. 缺陷的处理速度 2. 缺陷处理的状态 3. 缺陷的分布 4. 缺陷产生的原因 使用Leangoo敏捷看板我们可以对缺陷进行可视化的管理&#xff0c;方便我们对缺陷的处理进展、负责人、当前状态、分布情况等各个方面一目了然。 下面我们…

ATFX汇市:美元指数延续反弹态势,USDCHF年内已涨超2%

ATFX汇市&#xff1a;上周五和本周一&#xff0c;美元指数均以阳线收盘。今日盘中&#xff0c;美元指数呈中阳线形态&#xff0c;如果晚间的美国1月纽约联储制造业指数没有爆冷&#xff0c;美元指数今日以阳线收盘的概率极高。连续三日以阳线收盘&#xff0c;意味着美元指数的反…

文件的创建时间可以修改吗,怎么改?

文件的创建时间可以修改吗&#xff0c;怎么改&#xff1f;文件的创建时间是由操作系统自动生成并记录的&#xff0c;通常情况下无法直接修改。创建时间是文件的属性之一&#xff0c;它反映了文件在文件系统中的生成时间。一旦文件被创建&#xff0c;其创建时间就被确定下来&…

FEP水质取样器应用环境检测无溶出析出深水取样器

FEP水质取样器是一种用于采集水样的工具&#xff0c;它具有以下特点&#xff1a; 1.抗腐蚀性强&#xff1a;FEP材料具有出色的耐腐蚀性&#xff0c;可以在各种恶劣的水质环境中使用。 2.热稳定性好&#xff1a;FEP材料具有良好的热稳定性&#xff0c;能够在高温环境下保持结构完…

发送HTTP POST请求并处理响应

发送HTTP POST请求并处理响应是Web开发中的常见任务。在Go语言中&#xff0c;可以使用net/http包来发送HTTP POST请求并处理响应。 以下是一个示例代码&#xff0c;演示了如何发送HTTP POST请求并处理响应&#xff1a; go复制代码 package main import ( "b…

MessageBox:HubSpot x Facebook全方位对接!

在当今数字化营销的浪潮中&#xff0c;将多个业务系统高效整合成为推动企业成功的核心。HubSpot作为一体化的市场营销平台&#xff0c;与Facebook的整合通过强大的工具——MessageBox&#xff0c;为企业提供了更灵活、高效的整合方案。今天运营坛将深入探讨在HubSpot平台上整合…

Intel Processor Trace(一)

文章目录 前言一、Features and Capabilities1.1 Packet Summary 二、Intel Processor Trace Operational Model2.1 Change of Flow Instruction (COFI) Tracing2.1.1 Direct Transfer COFI2.1.2 Indirect Transfer COFI2.1.3 Far Transfer COFI 2.2 Software Trace Instrument…

PLC远程控制网关:实现智能化生产的关键

近年来&#xff0c;随着工业自动化的快速发展&#xff0c;越来越多的企业开始采用PLC远程控制网关来实现生产过程的智能化管理。这种创新的技术不仅能够提高生产效率&#xff0c;还可以降低成本&#xff0c;并且为企业带来更多的商业机会。 PLC远程控制网关是一种基于互联网的…

贵阳贵安持续打造面向全国的算力保障基地

作者&#xff1a;黄玉叶 当前&#xff0c;新一轮科技革命和产业变革正在重塑全球经济结构&#xff0c;算力作为数字经济的核心生产力&#xff0c;成为全球战略竞争的新焦点。2021年5月&#xff0c;国家发展改革委、中央网信办、工业和信息化部、国家能源局联合印发《全国一体化…

【昕宝爸爸小模块】深入浅出之JDK21 中的虚拟线程到底是怎么回事(二)

➡️博客首页 https://blog.csdn.net/Java_Yangxiaoyuan 欢迎优秀的你&#x1f44d;点赞、&#x1f5c2;️收藏、加❤️关注哦。 本文章CSDN首发&#xff0c;欢迎转载&#xff0c;要注明出处哦&#xff01; 先感谢优秀的你能认真的看完本文&…

Linux------进程的fork()详解

目录 前言 一、fork()的使用 二、fork()的返回值 我们为什么要创建子进程&#xff1f; 父进程与子进程的分流 三、fork的一些难理解的问题 1.fork干了什么事情&#xff1f; 2.fork为什么会有两个返回值 3.fork的两个返回值&#xff0c;为什么会给父进程返回子进程pid…

Linux Mii management/mdio子系统分析之六 fixed-mii_bus分析(mac2mac分析)

&#xff08;转载&#xff09;原文链接&#xff1a;[https://blog.csdn.net/u014044624/article/details/130674908] (https://blog.csdn.net/u014044624/article/details/130674908) 前面几章我们介绍了MDIO模块的大部分内容&#xff0c;针对mii_bus、mdio_bus、phy_device、p…

鸿蒙开发的前景趋势及薪资水平展望

随着科技的迅猛发展和数字化转型的推进&#xff0c;鸿蒙系统作为国内领先的分布式操作系统&#xff0c;已经在市场中崭露头角&#xff0c;展现出独特的技术优势和广阔的应用前景。对于开发者而言&#xff0c;掌握鸿蒙开发技能不仅意味着拥有更多的职业发展机会&#xff0c;还预…

Win10输入密码不满足密码策略要求的解决方法

在Win10电脑中用户输入密码的时候&#xff0c;收到了不满足密码策略要求的提示&#xff0c;导致用户不能成功设置密码。用户先打开Win10系统的组策略编辑器&#xff0c;点击关闭密码必须符合复杂性要求功能保存即可。以下小编将分享Win10密码不符合策略要求的解决方法步骤&…

Relation-Aware Graph Transformer for SQL-to-Text Generation

Relation-Aware Graph Transformer for SQL-to-Text Generation Abstract SQL2Text 是一项将 SQL 查询映射到相应的自然语言问题的任务。之前的工作将 SQL 表示为稀疏图&#xff0c;并利用 graph-to-sequence 模型来生成问题&#xff0c;其中每个节点只能与 k 跳节点通信。由…

Linux -- firewalld的富语言规则

1. Firewalld支持两种类型的NAT&#xff1a;IP地址伪装和端口转发。 &#xff08;1&#xff09;IP地址伪装 地址伪装&#xff08;masquerade)&#xff1a;通过地址伪装&#xff0c;NAT 设备将经过设备的包转发到指定接收方&#xff0c;同时将通过的数据包的源地址更改为其自己的…

WBTT:“Fair Launch”如何做到更加公平

铭文是一种全新的资产发行方案&#xff0c;它让非图灵完备的链上生态具备发行资产的能力&#xff0c;而铭文赛道的兴起也让比特币生态再次回到加密世界的中心。铭文市场的兴起&#xff0c;更被称之为“散户的狂欢”&#xff0c;因为这种“Fair Launch”的启动方式正在让所有参与…

Webpack 怎么实现按需异步加载模块

要弄懂这个问题&#xff0c;需要先来看关于webpack打包的3个问题。 三个问题 第一个问题 项目中的json文件&#xff0c;如何使用webpack进行处理&#xff1f; 如果我们希望把json文件当做静态配置&#xff0c;例如有如下json文件 {"version": "1.0.0"…