1 条题解

  • 0
    @ 2025-5-19 19:42:03

    算法思想

    先预处理前缀和与后缀和数组,记录各位置前 / 后各组奶牛数量;然后分别枚举升序和降序的分割点,利用前缀和快速计算不同分割下的修改次数(如前 i 个为 1 组、中间为 2 组、剩余为 3 组的情况),通过优化枚举过程(仅考虑边界点)将时间复杂度降至 O (N);最后取两种顺序的最小修改次数作为结果。

    代码

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    int main() {
        int N;
        cin >> N;
        vector<int> D(N);
        for (int i = 0; i < N; ++i) {
            cin >> D[i];
        }
    
        // Precompute prefix sums for not 1, not 2, not 3
        vector<int> cnt1(N + 1, 0), cnt2(N + 1, 0), cnt3(N + 1, 0);
        for (int i = 1; i <= N; ++i) {
            cnt1[i] = cnt1[i - 1] + (D[i - 1] != 1);
            cnt2[i] = cnt2[i - 1] + (D[i - 1] != 2);
            cnt3[i] = cnt3[i - 1] + (D[i - 1] != 3);
        }
    
        // Case 1: non-decreasing 1, 2, 3
        int min_inc = N; // Initialize with maximum possible changes
        // Precompute min of (cnt1[i] - cnt2[i]) for i <= j
        vector<int> min_diff_inc(N + 1);
        int current_min = 0;
        for (int j = 0; j <= N; ++j) {
            if (j == 0) {
                current_min = cnt1[0] - cnt2[0];
            } else {
                current_min = min(current_min, cnt1[j] - cnt2[j]);
            }
            min_diff_inc[j] = current_min;
        }
        for (int j = 0; j <= N; ++j) {
            int temp = min_diff_inc[j] + cnt2[j] + (cnt3[N] - cnt3[j]);
            if (temp < min_inc) {
                min_inc = temp;
            }
        }
    
        // Case 2: non-increasing 3, 2, 1
        int min_dec = N;
        // Precompute min of (cnt3[i] - cnt2[i]) for i <= j
        vector<int> min_diff_dec(N + 1);
        current_min = 0;
        for (int j = 0; j <= N; ++j) {
            if (j == 0) {
                current_min = cnt3[0] - cnt2[0];
            } else {
                current_min = min(current_min, cnt3[j] - cnt2[j]);
            }
            min_diff_dec[j] = current_min;
        }
        for (int j = 0; j <= N; ++j) {
            int temp = min_diff_dec[j] + cnt2[j] + (cnt1[N] - cnt1[j]);
            if (temp < min_dec) {
                min_dec = temp;
            }
        }
    
        // Also consider all same (1, 1, 1), (2, 2, 2), (3, 3, 3)
        int min_same = min(cnt1[N], min(cnt2[N], cnt3[N]));
    
        // The answer is the minimum of all cases
        int answer = min(min_inc, min(min_dec, min_same));
        cout << answer << endl;
    
        return 0;
    }
    
    • 1

    信息

    ID
    2671
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者