#P2932. 第1题-货物配送
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 541
            Accepted: 172
            Difficulty: 3
            
          
          
          
                       所属公司 : 
                              华为
                                
            
                        
              时间 :2025年5月7日-暑期实习(留学生)
                              
                      
          
 
- 
                        算法标签>贪心算法          
 
第1题-货物配送
题解
题目描述
某公司有 2 个仓库(用 A 和 B 表示),需要给 m(m 为偶数)个营业网点各配送一件货物。假设每个仓库正好都有 2m 件货物,配送给不同营业网点的费用使用一个二维数组 cost 表示,其中
cost[i]=[Ai,Bi]表示第 i 个营业网点从 A 仓发货的运费为 Ai,从 B 仓库发货的费用为 Bi。请计算 m 件货物配送的最低费用,要求每个营业网点都有一件货物送到。
思路
- 初始假设:若全部从仓库 A 发货,则总费用为i=1∑mAi.
 - 差值定义:将第 i 个网点改为从 B 发货,相当于在全部发自 A 的基准上“多花”Δi=Bi−Ai 的费用。
 - 选择最优:需要有且仅有 2m 件货物由 B 发货。为了使额外总费用最小,应当 选取最小的 2m 个 Δi(即最负或最小的那些差值)去改由 B 发货。
 - 计算答案:

 
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
    int m;
    cin >> m;
    string line;
    // 读取第二行的数组字符串
    getline(cin, line);           // 读掉行尾
    getline(cin, line);           // 真正的数组行
    vector<pair<int,int>> cost;
    // 提取所有整数
    vector<int> nums;
    int num = 0;
    bool inNum = false;
    for (char c : line) {
        if (isdigit(c)) {
            num = num * 10 + (c - '0');
            inNum = true;
        } else if (inNum) {
            nums.push_back(num);
            num = 0;
            inNum = false;
        }
    }
    if (inNum) nums.push_back(num);
    // 两两配对成 cost[i]
    for (int i = 0; i < nums.size(); i += 2) {
        cost.emplace_back(nums[i], nums[i+1]);
    }
    // 1. 计算全部从 A 发货的初始费用
    long long sumA = 0;
    for (auto &p : cost) {
        sumA += p.first;
    }
    // 2. 计算差值数组 Δ[i] = B_i - A_i
    vector<int> diff;
    for (auto &p : cost) {
        diff.push_back(p.second - p.first);
    }
    // 3. 对差值排序,取最小的 m/2 个
    sort(diff.begin(), diff.end());
    long long extra = 0;
    for (int i = 0; i < m/2; ++i) {
        extra += diff[i];
    }
    // 4. 输出最小总费用
    cout << (sumA + extra) << endl;
    return 0;
}
Python
# -*- coding: utf-8 -*-
import sys
def main():
    # 读取输入
    m = int(sys.stdin.readline().strip())
    line = sys.stdin.readline().strip()
    # 提取所有整数
    nums = []
    num = 0
    in_num = False
    for c in line:
        if c.isdigit():
            num = num * 10 + int(c)
            in_num = True
        elif in_num:
            nums.append(num)
            num = 0
            in_num = False
    if in_num:
        nums.append(num)
    # 构造 cost 列表
    cost = [(nums[i], nums[i+1]) for i in range(0, len(nums), 2)]
    
    # 计算全部从 A 发货的费用
    sumA = sum(a for a, b in cost)
    # 计算差值列表 Δ = B_i - A_i
    diffs = sorted(b - a for a, b in cost)
    # 取最小的 m/2 个差值并累加
    extra = sum(diffs[:m//2])
    # 输出结果
    print(sumA + extra)
if __name__ == "__main__":
    main()
Java
import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int m = Integer.parseInt(br.readLine().trim());
        String line = br.readLine().trim();
        
        // 提取所有数字
        List<Integer> nums = new ArrayList<>();
        int num = 0;
        boolean inNum = false;
        for (char c : line.toCharArray()) {
            if (Character.isDigit(c)) {
                num = num * 10 + (c - '0');
                inNum = true;
            } else if (inNum) {
                nums.add(num);
                num = 0;
                inNum = false;
            }
        }
        if (inNum) {
            nums.add(num);
        }
        
        // 构造 cost 列表
        List<int[]> cost = new ArrayList<>();
        for (int i = 0; i < nums.size(); i += 2) {
            cost.add(new int[]{nums.get(i), nums.get(i+1)});
        }
        
        // 计算全部从 A 发货的费用
        long sumA = 0;
        for (int[] p : cost) {
            sumA += p[0];
        }
        // 计算差值列表,并排序
        List<Integer> diffs = new ArrayList<>();
        for (int[] p : cost) {
            diffs.add(p[1] - p[0]);
        }
        Collections.sort(diffs);
        
        // 累加最小的 m/2 个差值
        long extra = 0;
        for (int i = 0; i < m/2; i++) {
            extra += diffs.get(i);
        }
        // 输出最小总费用
        System.out.println(sumA + extra);
    }
}
        题目内容
某公司有 2 个仓库(用 A 和 B 表示),需要给 m ( m 为偶数)个营业网点各配送一件货物。假设每个仓库正好都有 m/2 件货物,配送给不同营业网点的费用使用一个二维数组 cost 表示,其中 cost[i]=[Ai,Bi],表示第 i 个营业网点从 A 仓发货的运费为 Ai ,从 B 仓库发货的费用为 Bi 。请计算 m 件货物配送的最低费用,要求每个营业网点都有一件货物送到。
输入描述
第一行是一个整数 M ,代表营业网点数量。2<M<=100, M 为偶数第二行是一个长度为 M 的二维数组 cost ,其中 cost[i]=[Ai,Bi],Ai 和 Bi 分别表示从 A、B 仓库发货的费用。
1<=Ai,Bi<=1000
输出描述
一个整数,表示最低费用
样例1
输入
2
[[10,30],[30,200]]
输出
60
说明
2 个营业网点,每个仓库备有 1 件货物
第 1 个营业网点从 B 发货,费用 30
第 2 个营业网点从 A 发货,费用 30
样例2
输入
4
[[10,30],[30,200],[300,50],[40,20]]
输出
110
说明
4个营业网点,每个仓库有2件货物
第 1 个营业网点从 A 发货,费用 10
第 2 个营业网点从 A 发货,费用 30
第 3 个营业网点从 B 发货,费用 50
第 4 个营业网点从 B 发货,费用 20