53 std::cout <<
"------------------------------------------------------------\n";
68 std::cout <<
"[1] Divide & Conquer DP optimization\n";
73 const size_t n = demand.
size();
78 for (
size_t i = 0; i < n; ++i)
81 const auto cost = [&] (
const size_t k,
const size_t i) ->
long long
91 std::cout <<
"Demand sequence: ";
92 for (
size_t i = 0; i < n; ++i)
93 std::cout << demand[i] << (i + 1 == n ?
'\n' :
' ');
95 std::cout <<
"Groups: " <<
groups <<
"\n";
96 std::cout <<
"Optimal cost: " <<
res.optimal_cost <<
"\n";
102 for (
size_t g =
groups; g-- > 1; )
104 const size_t k =
res.split[g + 1][i];
110 std::cout <<
"Split points (prefix indices): ";
111 for (
size_t p = bounds.
size(); p-- > 0; )
113 std::cout << bounds[p];
131 std::cout <<
"[2] Knuth optimization (optimal adjacent merge)\n";
137 std::cout <<
"Blocks: ";
138 for (
size_t i = 0; i < blocks.
size(); ++i)
139 std::cout << blocks[i] << (i + 1 == blocks.
size() ?
'\n' :
' ');
141 std::cout <<
"Minimum merge cost: " <<
res.optimal_cost <<
"\n";
142 std::cout <<
"Top split (k for [0,n)): "
143 <<
res.opt[0][blocks.
size()] <<
"\n";
160 std::cout <<
"[3] CHT + Li Chao (geometry-friendly lower envelopes)\n";
163 std::cout <<
"Monotone-slope CHT for min y = m*x + b:\n";
167 cht.add_line(-1, 10);
168 cht.add_line(-4, 25);
170 for (
long long x = -4; x <= 8; x += 3)
171 std::cout <<
" x=" << std::setw(3) << x
172 <<
" min=" << std::setw(5) <<
cht.query(x) <<
"\n";
174 std::cout <<
"\nGeometric application: weighted squared distance\n";
175 std::cout <<
" min_j ((x_i - x_j)^2 + w_j) via Li Chao\n\n";
183 << std::left << std::setw(8) <<
"x_i"
184 << std::setw(8) <<
"w_i"
185 << std::setw(12) <<
"min value"
188 for (
size_t i = 0; i <
xs.size(); ++i)
191 << std::left << std::setw(8) <<
xs[i]
192 << std::setw(8) <<
ws[i]
193 << std::setw(12) <<
best[i]
210 std::cout <<
"[4] Monotone queue optimization (windowed transitions)\n";
215 const size_t window = 3;
219 std::cout <<
"Base cost: ";
220 for (
size_t i = 0; i < base.
size(); ++i)
221 std::cout << base[i] << (i + 1 == base.
size() ?
'\n' :
' ');
223 std::cout <<
"Window: " << window <<
"\n";
224 std::cout <<
"Final minimum cost: " <<
res.dp[base.
size() - 1] <<
"\n";
227 size_t i = base.
size() - 1;
235 std::cout <<
"Chosen chain: ";
236 for (
size_t p = path.
size(); p-- > 0; )
238 std::cout << path[p];
261 std::cout <<
"\n=== DP Optimizations: D&C, Knuth, CHT/Li Chao, Monotone Queue ===\n\n";
268 std::cout <<
"Done.\n";
Classical DP optimization toolkit: D&C DP, Knuth, CHT, Li Chao, and monotone-queue transitions.
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
T & append(const T &data)
Append a copy of data
Convex Hull Trick for minimum queries.
void add_line(const T slope, const T intercept)
Insert a new line; slopes must be non-increasing.
int main()
Runs the DP optimization demonstration suite and exits.
Main namespace for Aleph-w library functions.
Array< T > min_weighted_squared_distance_1d(const Array< T > &xs, const Array< T > &weights)
Weighted squared-distance lower envelope on a line.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
Knuth_Optimization_Result< size_t > optimal_merge_knuth(const Array< size_t > &weights)
Optimal adjacent merge cost via Knuth optimization.