zoukankan      html  css  js  c++  java
  • LC410. Split Array Largest Sum

    把一个数组分成m个连续子数组(不能有空数组),求所有分法中,子数组sum的最大值的最小值。

    方法1:容易想到的是动态规划

    dp[i][j] = min(max(dp[k-1][j-1], sum[k][i]) 1 <= k <= i, dp[i][j]表示用前i个数字,分成j组,最大和的最小值

    time:$O(nnm)$ space:$O(nm)$

    class Solution {
    public:
        typedef long long ll;
        ll INF = 1e15;
        int splitArray(vector<int>& nums, int m) {
            int n = nums.size();
            vector<vector<ll>> dp(n + 1, vector<ll>(m + 1, INF));
            dp[0][0] = 0;
            vector<ll> sums(n + 1, 0);
            for (int i = 0; i < n; ++i) sums[i + 1] = sums[i] + nums[i];
            for (int i = 1; i <= n; ++i) {
                for (int j = 1; j <= m; ++j) {
                    for (int k = 1; k <= i; ++k) {
                        dp[i][j] = min(dp[i][j], max(dp[k - 1][j - 1], sums[i] - sums[k - 1]));
                    }
                }
            }
            return dp[n][m];
        }
    };

    方法2:贪心+二分

     check(LL sum, vector<int>& nu) 函数判断数组能否被分成m段,最大的和不超过sum,用了贪心的思路,cnt表示最少能分多少段,使最大和不超过sum,因此,分当前段的时候,取尽可能多的数,如果最后cnt <= m,说明我肯定能分出m段,如果cnt < m,只要拆开一些段就行,最大和并不会变坏。假如某个数大于sum,则无论怎么分,都无法分出m(m > 1)段。
    然后用二分去找最小的sum,能使check返回true,相当于找lower_bound

    class Solution {
    public:
        typedef long long LL;
        int m;
        bool check(LL sum, vector<int>& nu) {
            LL nsum = 0;
            int cnt = 1;
            for (int i : nu) {
                if (i > sum) return false;
                if (i + nsum > sum) {
                    cnt++;
                    nsum = i;
                }
                else 
                    nsum += i;
            }
            return cnt <= m;
        }
        int splitArray(vector<int>& nums, int m) {
            int n = nums.size();
            this->m = m;
            LL l = 0, r = 0;
            for (int i : nums) r += i;
            LL mid, ans = r;
            while (l <= r) {
                mid = (l + r) >> 1;
                if (check(mid, nums)) {
                    ans = min(ans, mid);
                    r = mid - 1;
                }
                else l = mid + 1;
            }
            return ans;
        }
    };
  • 相关阅读:
    luffy后台登录+注册+课程
    luffy前台登录+注册+课程
    luffy前台准备
    luffy后台准备
    跨域请求
    pip源和虚拟环境的搭建
    Book接口
    drf-Xadmin的使用
    drf-JWT认证
    drf-自动生成接口文档
  • 原文地址:https://www.cnblogs.com/betaa/p/12529990.html
Copyright © 2011-2022 走看看