37# include <gtest/gtest.h>
52 constexpr long long INF64 = std::numeric_limits<long long>::max() / 4;
60 for (
size_t g = 0; g <=
groups; ++g)
63 for (
size_t i = 0; i <= n; ++i)
70 for (
size_t g = 1; g <=
groups; ++g)
71 for (
size_t i = g; i <= n; ++i)
72 for (
size_t k = g - 1;
k < i; ++
k)
76 const long long cand = dp[g - 1][
k] + cost(
k, i);
86 const size_t n =
w.
size();
92 for (
size_t i = 0; i < n; ++i)
97 for (
size_t i = 0; i <= n; ++i)
100 for (
size_t j = 0; j <= n; ++j)
102 dp.
append(std::move(row));
105 for (
size_t len = 2; len <= n; ++len)
106 for (
size_t i = 0; i + len <= n; ++i)
108 const size_t j = i + len;
109 size_t best = std::numeric_limits<size_t>::max();
110 const size_t seg =
pref[j] -
pref[i];
111 for (
size_t k = i + 1;
k < j; ++
k)
113 const size_t cand = dp[i][
k] + dp[
k][j] + seg;
125 if (base.
size() == 0)
133 for (
size_t i = 1; i < base.
size(); ++i)
135 const size_t l = (i >
w) ? (i -
w) : 0;
137 for (
size_t j =
l; j < i; ++j)
140 dp(i) =
best + base[i];
143 return dp[base.
size() - 1];
151 for (
size_t j = 0; j <
xs.size(); ++j)
153 const long long d =
xs[i] -
xs[j];
154 const long long cand = d * d +
ws[j];
165 std::mt19937
rng(20260226);
169 const size_t n = 1 + (
rng() % 36);
170 const size_t groups = 1 + (
rng() % std::min<size_t>(6, n));
174 for (
size_t i = 0; i < n; ++i)
175 a.
append(1 +
static_cast<long long>(
rng() % 11));
179 for (
size_t i = 0; i < n; ++i)
182 const auto cost = [&] (
const size_t k,
const size_t i) ->
long long
195 for (
size_t g = 1; g <=
groups; ++g)
196 for (
size_t i = g + 1; i <= n; ++i)
197 EXPECT_LE(fast.split[g][i - 1], fast.split[g][i]);
203 const auto cost = [] (
const size_t k,
const size_t i) ->
long long
205 const long long d =
static_cast<long long>(i -
k);
221 std::mt19937
rng(20260226 + 7);
225 const size_t n =
rng() % 35;
228 for (
size_t i = 0; i < n; ++i)
229 w.append(
static_cast<size_t>(
rng() % 25));
236 for (
size_t len = 3; len <= n; ++len)
237 for (
size_t i = 0; i + len <= n; ++i)
239 const size_t j = i + len;
240 EXPECT_LE(fast.opt[i][j - 1], fast.opt[i][j]);
241 EXPECT_LE(fast.opt[i][j], fast.opt[i + 1][j]);
265 for (
size_t i = 0; i <
slopes.size(); ++i)
271 for (
long long x = -30; x <= 30; ++x)
274 for (
size_t i = 0; i <
lines.size(); ++i)
276 const long long v =
lines[i].value_at(x);
283 cht.reset_query_cursor();
284 for (
long long x = -30; x <= 30; ++x)
287 for (
size_t i = 0; i <
lines.size(); ++i)
289 const long long v =
lines[i].value_at(x);
319 std::mt19937
rng(20260226 + 17);
320 for (
size_t i = 0; i < 80; ++i)
322 const long long m =
static_cast<long long>(
rng() % 51) - 25;
323 const long long b =
static_cast<long long>(
rng() % 401) - 200;
328 for (
long long x = -200; x <= 200; x += 3)
331 for (
size_t i = 0; i <
lines.size(); ++i)
333 const long long cand =
lines[i].value_at(x);
354 std::mt19937
rng(20260226 + 31);
358 const size_t n = 1 + (
rng() % 200);
359 const size_t w = 1 + (
rng() % 20);
363 for (
size_t i = 0; i < n; ++i)
364 base.
append(1 +
static_cast<long long>(
rng() % 50));
371 for (
size_t i = 1; i < n; ++i)
402 for (
size_t i = 0; i <
xs.size(); ++i)
408 std::mt19937
rng(20260226 + 101);
412 const size_t n = 1 + (
rng() % 60);
419 for (
size_t i = 0; i < n; ++i)
421 xs.append(
static_cast<long long>(
rng() % 101) - 50);
422 ws.append(
static_cast<long long>(
rng() % 80));
426 for (
size_t i = 0; i < n; ++i)
440 if (std::getenv(
"RUN_PERF_TESTS") ==
nullptr)
441 GTEST_SKIP() <<
"Skipping performance test; set RUN_PERF_TESTS=1 to enable";
445 const size_t groups = 100;
446 const size_t n = 2000;
449 auto cost = [](
size_t i,
size_t j) ->
long long
451 const long long diff =
static_cast<long long>(j - i);
457 const std::clock_t
end_clock = std::clock();
463 <<
"Performance regression: divide_and_conquer_partition_dp took " <<
cpu_elapsed_ms <<
"ms CPU time";
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
void reserve(size_t cap)
Reserves cap cells into the array.
Convex Hull Trick for minimum queries.
Li Chao tree for min line queries on an integral x-domain.
Key * append(const Key &key)
Alias for insert() (copy version).
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
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.
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)