cppAcademy
← Learning PathLESSON 28 / 30 · DYNAMIC PROGRAMMING · 60 MIN✕

Knuth Optimization

Knuth optimization accelerates a particular interval-splitting recurrence when adjacent subproblem optima bound the new optimum. We solve minimum cost of merging adjacent groups in their fixed order. Merging an interval costs its total weight in addition to the two child merge costs. Nonnegative additive weights satisfy the theorem’s sufficient conditions, giving O(n²) instead of cubic split scanning.

Prerequisites: Interval DP; Prefix Sums; optimum-index monotonicity.

Build the idea

  1. Recognize the repeated subproblems

    The unrestricted optimal-merge heap may combine any pair; adjacent-only merging preserves leaf order and needs interval DP. There are O(n²) intervals and naively O(n) splits per interval. If opt[l][r−1]≤opt[l][r]≤opt[l+1][r], only a narrow range is necessary. This is stronger and different from the single-row monotonicity used by divide-and-conquer partition optimization.

  2. Define the state

    dp[l][r] is minimum cost to merge consecutive groups l…r into one, with dp[i][i]=0. W(l, r)=prefix[r+1]−prefix[l] is interval weight. opt[l][r] is the rightmost split attaining the minimum over k∈[l, r−1]. The tie convention is fixed in both theory and code. opt[i][i]=i initializes neighboring bounds.

  3. Derive the transition

    The direct recurrence is min(dp[l][k]+dp[k+1][r])+W(l, r). Knuth’s bound restricts k to opt[l][r−1]…min(r−1, opt[l+1][r]). Add W once for the final merge, not once per child. Prefix sums make W constant-time. The code uses ≤ on equal candidates to keep the rightmost minimizer.

    opt[l][r−1]≤opt[l][r]≤opt[l+1][r]

  4. Base cases and computation order

    Fill increasing interval lengths, so both child costs and the neighboring opt bounds are already known. The n=0 case returns zero before accessing a table; one group also costs zero. Larger intervals start at INF. Every tested child interval is valid and finite, so no unreachable-state arithmetic is needed under the complete adjacent-merge model.

  5. Correctness and invariant

    Sufficient Knuth conditions are interval monotonicity W(b, c)≤W(a, d) and quadrangle inequality W(a, c)+W(b, d)≤W(a, d)+W(b, c) for a≤b≤c≤d. Nonnegative additive weights satisfy the first, and the second holds with equality by canceling sums. Knuth’s theorem then establishes the two-sided optimum bounds, so pruning preserves the exact cubic recurrence. The candidate-range widths telescope across each length, producing O(n²) total work. Negative weights invalidate the stated sufficient-condition proof.

  6. Work the example

    For weights [10,20,30], two-group costs are 30 and 50. The final interval can split after the first or second group:costs are 110 and 90. Choose the second, so the result is 90. As an order warning,[10,100,10] has adjacent optimum 230 while unrestricted merging can first combine the two 10s for total 140; these are different problems.

    intervalcostrightmost split (1-based)
    1..101
    2..202
    1..2301
    2..3502
    1..3902

C++17 implementation

This is a complete program. Compile with C++17 and enter the input described below.

#include<iostream>
#include<vector>
#include<algorithm>
int main(){
    int n;
    std::cin>>n;
    std::vector<long long>prefix(n+1);
    for(int i=1;i<=n;++i){
        long long a;
        std::cin>>a;
        prefix[i]=prefix[i-1]+a;
    }
    if(n==0){
        std::cout<<0<<'\n';
        return 0;
    }
    const long long INF=4000000000000000000LL;
    std::vector<std::vector<long long>>dp(n,std::vector<long long>(n));
    std::vector<std::vector<int>>opt(n,std::vector<int>(n));
    for(int i=0;i<n;++i){
        opt[i][i]=i;
    }
    for(int length=2;length<=n;++length){
        for(int l=0;l+length<=n;++l){
            int r=l+length-1;
            dp[l][r]=INF;
            int low=opt[l][r-1],high=std::min(r-1,opt[l+1][r]);
            for(int k=low;k<=high;++k){
                long long value=dp[l][k]+dp[k+1][r]+prefix[r+1]-prefix[l];
                if(value<=dp[l][r]){
                    dp[l][r]=value;
                    opt[l][r]=k;
                }
            }
        } // Rightmost minimizers; additive nonnegative interval weights satisfy Knuth's sufficient
            // conditions.
    }
    std::cout<<dp[0][n-1]<<'\n';
}

Complexity analysis

O(n²) states and O(n²) total bounded split candidates by the telescoping optimum bounds, versus O(n³) without optimization. O(n²) dp/opt tables and O(n) prefix sums. Total cost≤(n−1)·sum(weights)<10^12 fits long long.

Common mistakes and edge cases. Knuth does not apply to every interval DP or matrix-chain cost. Verify both sufficient conditions or another valid theorem. Keep a consistent rightmost-minimum tie rule and clamp splits to r−1. Negative weights are excluded. Adjacent merging cannot use the unrestricted two-smallest heap.

Example input and output

Read n (0..1000), then n nonnegative weights≤10^6. Only adjacent groups may merge, at cost equal to their combined weight. Print minimum total merge cost.

Input

3
10 20 30

Output

90

For weights [10,20,30], two-group costs are 30 and 50. The final interval can split after the first or second group:costs are 110 and 90. Choose the second, so the result is 90. As an order warning,[10,100,10] has adjacent optimum 230 while unrestricted merging can first combine the two 10s for total 140; these are different problems.

Practical applications

Use for this recurrence form and costs satisfying the required inequalities, such as suitable ordered merge/optimal-BST models. Re-derive the cost function before adapting:an optimization’s name is not permission to prune arbitrary split choices.

Check your understanding

Why are nonnegative weights important in the given justification?

Put it into practice

Compare against cubic adjacent-merge DP for small random weights.

Show a hint

Include all zeros to verify ties and the neighboring split bounds.

Further reading