top1编程
← 返回题目
题解

【提高】花生采摘

1 条题解

  • 0
    @ 2026-7-29 0:15:20
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <climits>
    using namespace std;
    
    struct Node {
        int r, c, p;
        bool operator<(const Node& other) const {
            return p > other.p; // 降序
        }
    };
    
    int main() {
        int M, N, K;
        cin >> M >> N >> K;
    
        vector<Node> peanuts;
        for (int i = 0; i < M; ++i) {
            for (int j = 0; j < N; ++j) {
                int p;
                cin >> p;
                if (p > 0) {
                    peanuts.push_back({i, j, p});
                }
            }
        }
    
        // 排序:按花生数量从大到小
        sort(peanuts.begin(), peanuts.end());
    
        int max_peanuts = 0;
        int total = peanuts.size();
    
        // 枚举采摘前 t 个
        for (int t = 0; t <= total; ++t) {
            int sum_p = 0;
            vector<pair<int, int>> points;
            for (int i = 0; i < t; ++i) {
                sum_p += peanuts[i].p;
                points.push_back({peanuts[i].r, peanuts[i].c});
            }
    
            // 不能采花生时,时间至少是 2(进、出)
            if (t == 0) {
                if (K >= 2) {
                    max_peanuts = max(max_peanuts, 0);
                }
                continue;
            }
    
            // 求最小时间:枚举入口列和出口列
            int min_time = INT_MAX;
    
            // 尝试所有入口列(从第0行进入)
            for (int start_col = 0; start_col < N; ++start_col) {
                // 尝试所有出口列(从第0行退出)
                for (int end_col = 0; end_col < N; ++end_col) {
                    int time = 1; // 跳入第一行
                    time += t;    // 采摘时间(每棵1单位)
    
                    // 从入口开始走
                    int r_prev = 0, c_prev = start_col;
                    for (auto& pt : points) {
                        int r_curr = pt.first, c_curr = pt.second;
                        int dist = abs(r_curr - r_prev) + abs(c_curr - c_prev);
                        time += dist;
                        r_prev = r_curr;
                        c_prev = c_curr;
                    }
    
                    // 最后从最后一个点跳回路边
                    time += abs(r_prev - 0) + abs(c_prev - end_col);
                    time += 1; // 跳回路边
    
                    if (time <= K) {
                        min_time = min(min_time, time);
                    }
                }
            }
    
            if (min_time != INT_MAX) {
                max_peanuts = max(max_peanuts, sum_p);
            }
        }
    
        cout << max_peanuts << endl;
    
        return 0;
    }
    
    • 1