编程之美 2.18数组分割

1.插入法

import java.util.*;
public class Main{
    public static void main(String[] args) {
        int[] nums={1,5,7,8,9,6,3,11,20,17};
        int N=5;
        ArrayList<ArrayList<Integer>> lists=new ArrayList<ArrayList<Integer>>();
        for(int i=0;i<=N;i++){
            ArrayList<Integer> temp=new ArrayList<Integer>();
            lists.add(temp);
        }
        lists.get(0).add(0);
        int sum=0;
        for(int i=0;i<2*N;i++){
            for(int j=Math.min(i+1,N);j>0;j--){
                for(Integer temp:lists.get(j-1)){
                    lists.get(j).add(temp+nums[i]);
                }
            }
            sum+=nums[i];
        }
        int max=0;
        for(Integer temp:lists.get(N)){
            if(temp<=sum/2 && temp>max){
                max=temp;
            }
        }
        System.out.println(max);
    }
}

2.动态规划(可继续优化空间复杂度)

public class Test{
    public static void main(String[] args) {
        int[] nums={1,5,7,8,9,6,3,11,20,17};
        int N=5;
        int sum=0;
        for(int i=0;i<2*N;i++){
            sum+=nums[i];
        }
        int[][][] dp=new int[2*N+1][N+1][sum/2+1];
        for(int i=1;i<=2*N;i++){
            for(int j=1;j<=N;j++){
                for(int m=0;m<=sum/2;m++){
                    if(m>=nums[i-1]){
                        dp[i][j][m]=Math.max(dp[i-1][j][m],dp[i-1][j-1][m-nums[i-1]]+nums[i-1]);
                    }
                }
            }
        }
        System.out.println(dp[2*N][N][sum/2]);
    }
}

原文地址:https://www.cnblogs.com/xinyi-blog/p/8647238.html

时间: 2024-11-10 13:22:37

编程之美 2.18数组分割的相关文章

编程之美2.18 数组分割 原创解O(nlogn)的时间复杂度求解:

题目:有一个无序.元素个数为2n的正整数组,要求:如何能把这个数组分割为元素个数为n的两个数组,并使两个子数组的和最接近? 1 1 2 -> 1 1 vs  2 看题时,解法的时间复杂度一般都大于或等于O(n^2).突然灵感一闪,发现一个新的解法,应该算是一个动态规划的过程吧,思路比较简单,请看代码.空间复杂度O(nlogn),时间复杂度O(n).但是不能确定是否适用所有正整数组,如果有错,请给出你的测试用例,谢谢! 代码如下: 1 1 #include <iostream> 2 2 #

编程之美2.18—数组分割

题目: 有一个没有排序,元素个数为2N的正整数数组.要求把它分割为元素个数为N的两个数组,并使两个子数组的和最接近. 基本思想: 假设数组A[1..2N]所有元素的和是SUM.模仿动态规划解0-1背包问题的策略,令S(k, i)表示前k个元素中任意i个元素的和的集合. 显然: S(k, 1) = {A[i] | 1<= i <= k} S(k, k) = {A[1]+A[2]+-+A[k]} S(k, i) = S(k-1, i) U {A[k] + x | x属于S(k-1, i-1) }

【编程之美】求数组的子数组之和的最大值

一个有N个整数元素的一维数组A[0],A[1],......,A[n-1],这个数组当然有很多子数组,那么子数组的最大值是什么呢? 分析与解法 我们先明确题意: 1. 题目说的子数组,是连续的: 2. 题目只需要求和,并不需要返回子数组的具体位置: 3. 数组中的元素是整数,所以数组可能包含有正整数.零.负整数: 4. 子数组不为空. 解法一:枚举 最简单的办法就是枚举所有的i和j,计算sum[i..j] = A[i]+A[i+1]+...+A[j],遍历所有可能的sum[i..j],找到最大值

【编程之美】寻找数组中的最大值和最小值

数组是最简单的一种数据结构.我们经常碰到的一个基本问题,就是寻找整个数组中最大的数,或者最小的数.这时,我们都会扫描一遍数组,把最大(最小)的数找出来.如果我们需要同时找出最大和最小的数呢? 对于一个由N个整数组成的数组,需要比较多少次才能把最大和最小的数找出来呢? 分析与解法 解法一:分别求最大和最小值 可以分别求出数组的最大值和最小值,这样,我们需要比较2N次才能求解. 解法二:分组求解 (1) 按顺序将数组中相邻的两个数分在同一组: (2) 比较同一组的两个数,将大的数放在偶数位上,小的放

【编程之美】目录

第1章  游戏之乐——游戏中碰到的题目 1.1 让CPU占用率听你的指挥 1.2 中国象棋将帅问题 1.3 一摞烙饼的排序 1.4 买书问题 第2章  数字之魅——数字中的技巧 2.1 求二进制中1的个数 2.2 不要被阶乘吓倒 2.3 寻找发帖"水王" 2.4 1的数目 2.5 寻找最大的K个数 2.6 精确表达浮点数 2.7 最大公约数问题 2.8 找符合条件的整数 2.9 斐波那契(Fibonacci)数列 2.10 寻找数组中的最大值和最小值 2.11 寻找最近点对 2.12

编程之美需整理的题目汇总

2.1 求二进制中1的个数. 2.2 求n!末尾有多少个0 和 求n!的二进制表示中最低位1的位置. 2.3 找出数量超过总数一半的记录. 扩展:3个发帖都超过了总数N的1/4. 2.4 十进制1~N 所有整数中1的个数: 满足F(N)=N的最大的N是多少. 扩展:CC上所有2的个数. 2.5 寻找最大的k的个数. 2.6 精确表达浮点数 2.7 最大公约数问题. 2.8 任意给定一个正整数N,求一个最小的正整数M(M>1),似的N*M的十进制表示形式里只有1和0. 2.9 Fibonacci

【编程之美】数组分割

有一个无序.元素个数为2n的正整数数组,要求:如何能把这个数组分割为元素个数为n的两个数组,并使两个子数组的和最接近? 分析与解法 从题目中可以分析出,题目的本质就是要从2n个整数中找出n个,使得它们的和尽可能地靠近所有整数之和的一半. 解法一:不靠谱的解法 先将数组的所有元素排序,然后划分为S1 = {a1, a3, ..., a2n-1}和S2 = {a2, a4, ..., a2n}: 从S1和S2中找出一对数进行交换,使得两个集合中所有元素的和之间的差值尽可能的小,直到找不到可对换的.

编程之美之2.14 求数组的子数组之和的最大值

[题目] 一个有N个整数元素的一维数组(A[0],A[1],A[2],...A[n-1]),这个数组中当然有很多子数组,那么子数组之和的最大值是多少? 该子数组是连续的. 我们先来明确一下题意: (1)子数组意味着是连续的. (2)题目只需要求和,并不需要返回子数组的具体位置. (3)数组的元素是整数,所以数组可能包含正整数,负整数或者零. 举几个例子: 数组:[1,-2,3,5,-3,2]返回8 数组:[0,-2,3,5,-1,2]返回9 数组:[-9,-2,-3,-5,-3]返回8 [解法一

编程之美-数组中最长递增子序列(包括输出)

#include <iostream> #define N 8 using namespace std; int main(){ int a[N]={1,-1,2,-3,4,-5,6,-7}; int lis[N]; int result[N];//结果 for(int i=0;i<N;i++) result[i]=0; for(int i=0;i<N;i++) { lis[i]=1; for (int j=0;j<i; j++) { if( a[i]> a[j] &a