#华为机试# 华为9.1机试Java版本实现(修复版)

华为机试第一题,参考牛客某大佬的Java动态规划实现,理了一下逻辑,修正了小bug。
package huawei;

import java.util.*;
/**
 * @author masterYHH
 * @version 1.0
 * @date 2021/9/2 00:31
 */

public class Test001 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 节点数k
        int k = Integer.parseInt(sc.nextLine());
        String[] str = sc.nextLine().split(" ");
        // k个节点转发能力数组
        int[][] capacity = new int[k + 1][2];
        int i = 1;
        for (String s : str) {
            String[] str1 = s.split(",");
            // 转发流量容量
            capacity[i][0] = Integer.parseInt(str1[0]);
            // 缓存流量容量
            capacity[i][1] = Integer.parseInt(str1[1]);
            i++;
        }
        // 初始流量
        int n = sc.nextInt();
        // DP状态:dp[i][0]为从i发送的数据包,dp[i][1]为第二次从i发送过来的数据包数量
        int[][] dp = new int[k + 1][2];
        // base case
        dp[0][0] = n;
        dp[0][1] = 0;
        dp[1] = dpFunction(dp[0], capacity[1]);
        int res = Math.min(dp[0][0] + dp[0][1], dp[1][0] + dp[1][1]);
        if (k == 0) {
            System.out.println(n);
        }
        if (k == 1) {
            System.out.println(res);
        }
        else {
            for (int j = 2; j <= k; j++) {
                // 上一个没坏,从上一个节点(j - 1)直接传到当前节点(j),没有故障
                int[] res1 = dpFunction(dp[j - 1], capacity[j]);
                // 上上一个节点(j - 2)传过来,上一个节点(j - 1)出现故障
                int[] res2 = dpFunction(dp[j - 2], capacity[j]);
                // 状态转移,选择值最小的一种传递方案
                dp[j] = res1[0] + res1[1] <= res2[0] + res2[1] ? res1 : res2;
            }
            // 最后一个节点坏掉或者正常情况比较较小值
            res = Math.min(dp[k][0] + dp[k][1], dp[k - 1][0] + dp[k - 1][1]);
            System.out.println(res);
        }
    }
    private static int[] dpFunction(int[] pre, int[] capacity) {
        // 第一次发送的数据包数量,根据节点发送能力判断
        int send1 = Math.min(pre[0], capacity[0]);
        // 第二次发送的数据包数量,比较三者得到最小值结果:
        // ①当前节点发送能力capacity[0],
        //  如果大于这个,多余的包也丢弃,无用
        // ②当前节点缓存能力和上一个节点缓存数据包数量,capacity[1] + pre[1],
        //  如果这个最小,说明当前节点缓存容量拉满,并且加上前一个节点的缓存包也没达到当前节点发送容量
        // ③前一个节点发送过来的包总量经当前节点发送后剩余的数据包数量,包括前一个包发送完剩余包数量,前一个节点缓存数量(把初始状态看作第0个节点)
        //  这种情况相比于情况②,说明当前节点的缓存能力没达到极限,所以得通过pre[0] - capacity[0]算出来
        // 逻辑:首先比较当前节点发送能力和前一个节点传过来的数据包数量,如果①小于②,则取①;再拿这个结果和①比较,取较小值
        int send2 = Math.min(pre[0] - capacity[0] + pre[1], capacity[0]);
        send2 = Math.min(send2, capacity[1] + pre[1]);
        return new int[]{send1, send2};
    }
}
仅供交流,欢迎反馈意见。
#华为机试##笔试题目##华为#
全部评论
不需要判断pre[0]-capacity[0]是否大于零吗,不然不是有出现这个值是负数的情况
1 回复 分享
发布于 2021-09-03 11:13
第二次发送数据的情况是不是想的复杂了?感觉第二轮就是单纯的接受上一节点传输过来的数据+该节点第一次缓存的数据,再和发送数据门限取最小就可以。机考的时候给的案例2,五个节点那道题,给的输出是20,你这个得到的是5
1 回复 分享
发布于 2021-09-05 16:19
    private static int[] dpFunction(int[] pre, int[] capacity) {         // 第一次发送的数据包数量,根据节点发送能力判断         int send1 = Math.min(pre[0], capacity[0]);         // 第二次发送的数据包数量,比较三者得到最小值结果:         // ①当前节点发送能力capacity[0],         //  如果大于这个,多余的包也丢弃,无用         // ②当前节点缓存能力和上一个节点缓存数据包数量,capacity[1] + pre[1],         //  如果这个最小,说明当前节点缓存容量拉满,并且加上前一个节点的缓存包也没达到当前节点发送容量         // ③前一个节点发送过来的包总量经当前节点发送后剩余的数据包数量,包括前一个包发送完剩余包数量,前一个节点缓存数量(把初始状态看作第0个节点)         //  这种情况相比于情况②,说明当前节点的缓存能力没达到极限,所以得通过pre[0] - capacity[0]算出来         // 逻辑:首先比较当前节点发送能力和前一个节点传过来的数据包数量,如果①小于②,则取①;再拿这个结果和①比较,取较小值         int cache = Math.min(Math.max(0,pre[0]-capacity[0]), capacity[1]);         int send2 = Math.min(cache+pre[1], capacity[0]);         return new int[]{send1, send2};     } LZ的版本第二段结尾几行稍微改一下应该没问题了,笔试时能快速想到动态规划真的牛批
1 回复 分享
发布于 2021-09-06 15:30
你好,这个是不是没考虑【不会同时有两个相连的节点损坏】这一条件呢
点赞 回复 分享
发布于 2021-09-12 18:55

相关推荐

断电再接线:1. 简历排版方面,你这内容比较少,一页放完。各模块之间建议用明显的分隔线分开,现在一眼看上去非常乱。教育经历留白太多。项目经历格式不统一。 2. 第一个项目,硬件设计太笼统,硬件架构规划是指板级电路设计还是FPGA逻辑设计?FPGA时序逻辑设计具体指的什么?实现的三个低速协议以及使用协议进行控制时序,是指什么? 3. 第二个项目,我觉得你可以和第一个项目整合一下,合并为一个项目。第二个项目说实话随便买个zynq开发板都有一直petalinux的教程,作为一个独立的项目不合适的,更像是一个小作业。 4. 第三个项目,项目内容这里,其实和环境搭建之类的东西提一嘴就好了,环境准备和编译安装工具链这种东西没多大必要写,实在要写的话可以 说 使用docker 独立sdk环境之类的。你说的这个工具我没用过,我用的比较多的是busybox和buildroot,是基于menuconfig进行配置的,如果scratch也是类似的模式的话,那我觉得这个项目也经不起细推。你可以往内核裁剪那方向靠,我说的这两个工具你也可以看看。 5. 你熟悉这些接口时序的话,你可以进一步去看一下驱动开发,然后面试的时候突出这个作为重点。第三个项目也可以将驱动开发给补充进去。因为单编内核和构建文件系统,其实很多时候是体力劳动。 6. 特长这里,独立成一个荣誉奖项的模块,把你获得的奖学金和竞赛奖项放一起。数模的话,写了国赛,美赛就不用写了。 7. 总的来说可以了,你简历上写的东西你只要都熟悉,找个实习还是没问题的。 8. 嵌入式分为硬件,底层软件和应用软件,看你的经历我建议你往底层靠,多去熟悉常用的通信接口,去看内核和驱动,网络编程这块也可以去了解一下。然后去**刷刷hot100
点赞 评论 收藏
分享
评论
8
31
分享

创作者周榜

更多
牛客网
牛客企业服务