《原神》甘雨的“重量级”时刻:当旅行者学会了“整理背包”_4
C 分治优化 DP 模板#include vector#include algorithmusing namespace std;const long long INF 1e18;//
定义代价计算函数// 示例计算区间 [l, r) 的代价long long cost(int l, int r, vectorlong long presum) {long long s presum[r] - presum[l];return s * (s
/ 2;}//
分治优化核心函数void solve(int l, int r, int optL, int optR, vectorvectorlong long dp, vectorlong long presum, int k) {if (l r) return;int mid (l r) / 2;long long best INF;int bestOpt optL;// 在 [optL, min(optR, mid-
] 范围内寻找最优分割点for (int i optL; i min(optR, mid -
; i) {long long current dp[k-1][i] cost(i, mid, presum);if (current best) {best current;bestOpt i;}}dp[k][mid] best;// 递归处理左右区间solve(l, mid - 1, optL, bestOpt, dp, presum, k);solve(mid 1, r, bestOpt, optR, dp, presum, k);}//
主 DP 函数vectorvectorlong long divideAndConquerDP(int K, int n, vectorlong long presum) {vectorvectorlong long dp(K1, vectorlong long(n1, INF));// 初始化划分1段时的代价for (int i 1; i n; i) {dp[1][i] cost(0, i, presum);}// 分治优化求解for (int k 2; k K; k) {solve(1, n, 1, n, dp, presum, k);}return dp;}//
问题入口函数long long solveProblem(vectorint nums, int k) {int n nums.size();vectorlong long presum(n 1,
;for (int i 0; i n; i) {presum[i1] presum[i] nums[i];}auto dp divideAndConquerDP(k, n, presum);return dp[k][n];}模板核心
可复用性只需要替换 cost() 函数就能适配不同的划分代价问题
时间复杂度O(k·n log n)比朴素 DP 的 O(k·n²) 效率高很多
适用场景当 DP 转移满足决策单调性时即最优分割点随区间右移单调不减就可以用这个模板
免费b站看大片真人电视剧男生-免费b站看大片真人电视剧男生应用