- 问答
站外题求解
- @ 2025-8-10 21:55:38

求代码。(不知道咋回事没有样例)
1 条评论
-
winterini LV 7 @ 2025-8-15 19:46:09我不知道这是哪道题目,所以我无法提交,还没样例,我手搓了一点样例,全部通过了
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll INF = 1e18; int main() { int n, k, q; cin >> n >> k >> q; vector<ll> a(n+1); vector<int> b(n+1); for (int i = 1; i <= n; i++) { cin >> a[i]; } for (int i = 1; i <= n; i++) { cin >> b[i]; } vector<ll> pre(n+1, 0); for (int i = 1; i <= n; i++) { pre[i] = pre[i-1] + a[i]; } vector<pair<int, int>> intervals; ll S0 = 0; for (int i = 0; i < q; i++) { int l, r; cin >> l >> r; intervals.push_back({l, r}); S0 += pre[r] - pre[l-1]; } vector<vector<ll>> cost(q, vector<ll>(k+1, INF)); for (int i = 0; i < q; i++) { int l = intervals[i].first; int r = intervals[i].second; cost[i][0] = 0; for (int t = 1; t <= k; t++) { int b_val = b[l]; if (l - b_val < 1 || r + b_val > n) { for (int j = t; j <= k; j++) { cost[i][j] = INF; } break; } ll left_sum = pre[l-1] - pre[l - b_val - 1]; ll right_sum = pre[r + b_val] - pre[r]; ll add_cost = left_sum + right_sum; cost[i][t] = cost[i][t-1] + add_cost; l = l - b_val; r = r + b_val; } } vector<ll> dp(k+1, INF); dp[0] = 0; for (int i = 0; i < q; i++) { for (int j = k; j >= 0; j--) { for (int t = 0; t <= k; t++) { if (t > j) break; if (cost[i][t] >= INF) continue; if (dp[j - t] >= INF) continue; if (dp[j] > dp[j - t] + cost[i][t]) { dp[j] = dp[j - t] + cost[i][t]; } } } } ll min_delta = *min_element(dp.begin(), dp.end()); ll ans = S0 + min_delta; cout << ans << endl; return 0; }解析题目
那读完题目,我们需要最小化给定区间在最多进行k次扩展操作后的区间和总和。每次扩展操作会扩展一个区间的左右端点,扩展量由当前左端点对应的b序列值决定。扩展后的区间不能越界,且每次操作只能选择一个区间进行扩展。我们的目标是合理分配k次操作,使得所有区间的区间和总和最小。
解题思路
那包是前缀和预处理,不然爆炸了
初始区间和总和,计算所有给定区间在未进行任何操作时的区间和总和(S0)。
对于每个区间,模拟最多k次扩展操作,记录每次操作带来的增量代价(即新增区间部分的a序列元素和)。
然后包是使用动态规划(背包DP)来分配k次操作(不然也炸),使得总增量代价最小。具体地:
将每个区间视为一组物品,其中操作t次对应的代价为该区间进行t次操作的总增量代价。
使用背包DP求解在总操作次数不超过k时的最小总增量代价。
结果计算:初始总和S0加上最小总增量代价即为最终答案。
样例测试
测试点 1:基础无修改情况
input
5 0 2 1 2 3 4 5 0 0 0 0 0 1 3 2 4output
15解释:因为 k = 0 无法进行区间修改操作。计算两个原始区间的和,第一个区间 [1,3] 的和为 1 + 2 + 3 = 6,第二个区间 [2,4] 的和为 2 + 3 + 4 = 9,总和 6 + 9 = 15 。
测试点 2:多区间修改决策
input
10 2 2 10 -1 -1 -1 10 -1 -1 -1 10 0 1 0 0 0 1 0 0 0 0 0 1 4 5 8output
14测试点 3:修改后和更大,选择不修改
input
4 2 1 5 6 7 8 1 1 1 1 2 3output
13解释:原始区间 [2,3] 和为 6 + 7 = 13 。若修改 1 次,区间变为 [2 - 1, 3 + 1] 即 [1,4] ,和为 5 + 6 + 7 + 8 = 26 ,比原始和大;修改 2 次左端点会小于 1 无法修改。所以最优选择是不修改,总和为 13 。
测试点 4:修改受边界限制
input
5 2 2 -3 1 -2 1 -4 0 1 0 0 1 2 2 5 5output
-8解释:第一个区间 [2,2] ,修改 1 次后变为 [2 - 1, 2 + 1] 即 [1,3] ,和为 -3 + 1 + (-2) = -4 ;修改 2 次左端点会小于 1 无法修改。第二个区间 [5,5] ,修改会使右端点超过 n(5 ),无法修改,和为 -4 。总和 -4 + (-4) = -8 。
申明:本代码不一定AC,如果提交有误,请提供错误信息,我会改的
- 1