首页 > 其他分享 >两个大小相同集合最接近的累加和 -dp

两个大小相同集合最接近的累加和 -dp

时间:2023-11-27 18:14:07浏览次数:29  
标签:arr int sum 累加 length 集合 dp

给定一个正数数组arr,请把arr中所有的数分成两个集合
如果arr长度为偶数,两个集合包含数的个数要一样多
如果arr长度为奇数,两个集合包含数的个数必须只差一个
请尽量让两个集合的累加和接近
返回最接近的情况下,较小集合的累加和

字节面试

暴力递归

	public static int right(int[] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        //计算arr数组的累加和
        int sum = 0;
        for (int nub : arr) {
            sum += nub;
        }
        //偶数长度
        if (arr.length % 2 == 0) {
            return process(arr, 0, arr.length / 2, sum / 2);
        } else { //奇数长度
            //注意此处应该取最大值。
            return Math.max(process(arr, 0, arr.length / 2, sum / 2), process(arr, 0, arr.length / 2 + 1, sum / 2));
        }

    }

    //从index位置开始向后遍历,找到picks个数字组成的最接近rest但不超过rest的累加和。
    public static int process(int[] arr, int index, int picks, int rest) {
        if (index == arr.length) {
            //如果返回-1的话,这种情况本身就是错误的。
            return picks == 0 ? 0 : -1;
        }
        //还没走到头
        if (picks == 0) {
            return 0;
        }
        //既没走到头,picks又不等于0
        //要当前位置的数。
        int p1 = -1;
        int next = -1;
        next = process(arr, index + 1, picks - 1, rest - arr[index]);

        if (next != -1 && arr[index] <= rest) {
            p1 = arr[index] + next;
        }
        //不要当前位置的数
        int p2 = process(arr, index + 1, picks, rest);

        return Math.max(p1, p2);
    }

dp方法优化

	public static int dp(int[] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        //计算arr数组的累加和
        int sum = 0;
        for (int nub : arr) {
            sum += nub;
        }
        //创建一个dp表
        int N = arr.length;
        int M = (N + 1) / 2;//向上取证办法,8 -> 4   9 -> 5
        sum /= 2;
        int[][][] dp = new int[N + 1][M + 1][sum + 1];
        //初始化所有的位置都是-1。
        for (int idnex1 = 0; idnex1 <= N; idnex1++) {
            for (int picks1 = 0; picks1 <= M; picks1++) {
                for (int rest1 = 0; rest1 <= sum; rest1++) {
                    dp[idnex1][picks1][rest1] = -1;
                }
            }
        }
        //初始化base case。
        for (int index1 = 0; index1 <= N; index1++) {
            for (int rest1 = 0; rest1 <= sum; rest1++) {
                dp[index1][0][rest1] = 0;
            }
        }
        //计算剩余位置。
        for (int index1 = N - 1; index1 >= 0; index1--) {
            for (int picks1 = 1; picks1 <= M; picks1++) {
                for (int rest1 = 0; rest1 <= sum; rest1++) {
                    int p1 = -1;
                    int next = -1;
                    if(rest1 - arr[index1] >= 0) {
                        next = dp[index1 + 1][picks1 - 1][rest1 - arr[index1]];
                    }
                    if (next != -1 && arr[index1] <= rest1) {
                        p1 = arr[index1] + next;
                    }
                    //不要当前位置的数
                    int p2 = dp[index1 + 1][picks1][rest1];
                    dp[index1][picks1][rest1] = Math.max(p1, p2);
                }
            }
        }
        //偶数长度
        if (arr.length % 2 == 0) {
            return dp[0][arr.length / 2][sum];
        } else { //奇数长度
            //注意此处应该取最大值。
            return Math.max(dp[0][arr.length / 2][sum], dp[0][arr.length / 2 + 1][sum]);
        }

注意dp优化的时候一定要按照暴力递归中的顺序来,先将基本的base case建设好,然后再向后进行一步一步的建设。

标签:arr,int,sum,累加,length,集合,dp
From: https://www.cnblogs.com/hi-terry-chen/p/17860002.html

相关文章

  • 随手写了个博客多平台发布脚本:Python自动发布文章到Wordpress
    引言作为一名技术博主,提高博客发布效率是我们始终追求的目标。在这篇文章中,我将分享一个基于Python的脚本,能够实现博客多平台发布,具体来说,是自动发布文章到WordPress。通过这个简单而高效的脚本,我们能够省去繁琐的手动发布步骤,提升工作效率。技术栈在编写这个自动发布脚本的过......
  • 通用串口modbus转PROFIBUS DP网关PM-160在汽车行业的应用案例
    通用串口modbus转PROFIBUSDP网关PM-160在汽车行业的应用案例摘要:PM-160是泗博公司生产的,可以实现串口与PROFIBUSDP协议数据通信的网关。此案例讲述的是通过PM-160网关,成功将梅特勒-托利多电子秤上的自定义协议数据传递给西门子PLC的应用案例说明。背景:某公司做轴承和汽......
  • 2023 合肥站 热身赛 B Problem F. Flower’s Land 换根dp 依赖背包
    传送门。求出包含某个点连通块大小为K的权值和最大值。钦定1为根节点,只求根节点的答案,其实是一个依赖性01背包问题可以\(nk\)的时间内解决。考虑进行换根操作,由于背包是取max的背包没办法进行背包的删除,然而取前后缀背包背包的合并为\(k^2\)复杂度过高。当时还有一个想法是点......
  • dpdk编译-meson版
     1 依赖python3的elftools,没有的话可以这样装python3-mpipinstallpyelftools2 在dpdk根目录,使用命令mesonsetup-Dprefix=/home/tong/Code/dpdk-21.11.4/dest/-Ddefault_library=static-Dprefer_static=true-Ddisable_drivers=net/mlx4build-Dprefix指明i......
  • java集合框架(一)Map的常见使用及循环的五中方式
    Map循环遍历的五种方法先使用Map方法定义数据Mapmap=newHashMap();map.put(0,"张三");map.put(1,"李四");map.put(2,"王五"); 1.通过key的set集合进行遍历,然后通过key来取map的valueSetset=map.keySet();for(Object......
  • java集合框架介绍
    Java集合框架是Java编程语言提供的一组框架,用于管理和操作数据集合。集合框架包含了一系列接口和类,可以用于存储、组织和处理数据。Java集合框架的核心是集合接口,这些接口定义了数据集合的基本行为和特性。下面,我们将详细介绍Java集合框架中的每个接口。@[toc]##一、Collection......
  • java List集合(ArrayList,LinkedList,Vector)
    Hii,mJinXiang⭐前言⭐本篇文章主要介绍java List集合的三种实现类ArrayList,LinkedList,Vector以及部分理论知识......
  • 集合框架(二)LinkedList的常见使用
    Hii,mJinXiang⭐前言 ⭐本篇文章主要介绍LinkedList的常见使用以及部分理论知识......
  • Arch Linux高分辨率屏幕设置分辨率及dpi缩放
    序言由于笔记本原生屏幕分辨率太渣,于是购入一块2440x1400、14英寸副屏。窗口管理器为dwm,使用startx命令进入环境注:此文不会改变tty的设置,仅设置xorg下某用户的个人设置目标实现:关闭笔记本屏幕,只使用副屏副屏分辨率设置为最高,且屏幕缩放设置为合适大小高分辨率小屏幕导致......
  • 微软RDP远程桌面优化
    微软RDP远程桌面优化介绍以下来自了解远程桌面协议(RDP)RDP基于T-120系列协议标准,并且是后者的扩展。支持多通道的协议允许单独的虚拟通道来传送以下信息:演示数据串行设备通信许可信息高度加密的数据,如键盘、鼠标活动RDP是T.Share核心协议的扩展。若干其他功......