美文网首页
cses 16:数组拆分问题

cses 16:数组拆分问题

作者: Plutorres | 来源:发表于2021-07-22 00:01 被阅读0次

描述

将一个数组分成两部分,使这两部分的和之差最小,求这个最小差值
n (1 ≤ n ≤ 20)
a_i (1 ≤ a_i ≤ 10^9)

分析

这题是一道非常经典的选数问题,思路是在一个数组中选一些数,使这些数的和在不大于数组元素总和一半 h(h = \lfloor \frac{sm}{2} \rfloor) 的前提下尽可能大。
首先这一题我优先想到的解法是 01 背包,开一个长度为 h + 1的数组滚动求解,时间复杂度 O(n^2),空间复杂度 O(h),但是在这一题中,h 的值可以达到非常大,我们开不了那么大的空间,所以并不合适。
注意到 n 的范围很小,所以可以采取暴力搜索的办法,可以根据 h 的值进行剪枝优化,时间复杂度 O(2^n),空间复杂度 O(n)

代码

// 分苹果问题
#include <cstdio>

typedef long long ll;
int a[25], n;
ll sm, ans;

void dfs(int cur, ll val) { // 第二个参数类型必须设为长整型,否则容易出错
    if (val * 2 > sm) return;
    if (cur == n) {
        if (val > ans) ans = val; // 剪枝优化
        return;
    }
    
    dfs(cur + 1, val + a[cur]);
    dfs(cur + 1, val);
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        sm += a[i];
    }
    
    dfs(0, 0);
    printf("%lld\n", sm - ans - ans);
    return 0;
}

相关文章

  • cses 16:数组拆分问题

    描述 将一个数组分成两部分,使这两部分的和之差最小,求这个最小差值 分析 这题是一道非常经典的选数问题,思路是在一...

  • 将数组拆分成固定长度数组

    #pragma mark -- 将数组拆分成固定长度 /** *将数组拆分成固定长度的子数组 * *@parama...

  • 无标题文章

    #pragma mark -- 将数组拆分成固定长度 /** *将数组拆分成固定长度的子数组 * *@parama...

  • C# 拆分byte[]数组

    将数组进行拆分,使用System.Array.Copy方法进行拆分。比如,原数组byte[] newData = ...

  • 数组拆分

    将一个数组按一定规则拆分成两个数组 奇数偶数拆分

  • 归并排序

    思路:将数组拆分,每次从中间拆分,直到不能拆分。然后将拆分到最后的数组,再慢慢的递归回来,按顺序一个个合并 算法实现

  • 排序:归并排序

    原理 拆分:将一个数组拆分成两个数组,左数组和右数组。然后声明一个空的新数组。 合并:比较两个数组最前面的元素,把...

  • cses 19:Grid Paths

    Grid Paths[https://cses.fi/problemset/task/1625/] 描述 在 的...

  • iOS 归并排序

      归并排序(Merge Sort)原理:将当前数组拆分成两个子数组,一直拆分到每个数组只有一个元素再重新依次有序...

  • 合并排序-golang

    合并排序 先对数组进行拆分,拆分成一个个单独的数字,然后再对拆分的数组进行合并。整体思路就是天下大事,分久必合。 ...

网友评论

      本文标题:cses 16:数组拆分问题

      本文链接:https://www.haomeiwen.com/subject/xgmsmltx.html