求代码。(不知道咋回事没有样例)

1 条评论

  • @ 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 4  
    

    output

    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 8  
    

    output

    14
    

    测试点 3:修改后和更大,选择不修改

    input

    4 2 1  
    5 6 7 8  
    1 1 1 1  
    2 3  
    

    output

    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 5  
    

    output

    -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,如果提交有误,请提供错误信息,我会改的

    • @ 2025-8-15 20:50:38

      orz%%%,感谢大佬!!!AC了!!!

  • 1