【题解】A18535.来自领导的烦恼

题目跳转

思路:本题可以使用动态规划或递归的方式来实现,本质上是一道01背包的变型题。假设一共有\(n\)名员工,每一位员工的技能水平用\(a[i]\)表示。要使得两个部门的员工技能总和之差最小,意思就是尽可能地将一个部门的技能之和”凑“到\(\sum\limits_{i=1}^{n}a[i] \times \frac{1}{2}\),也就是所有员工技能总和的一半。套用背包问题的模板,每一位员工就是每一件“物品”,背包的容量就是“所有员工技能总和的二分之一”。

时间复杂度分析:本题通过两个for循环来填写dp表格,外层循环遍历每一个员工,内层循环遍历所有员工的技能水平之和。外层循环执行\(n\)次,内层循环执行\(a[i]/2\)次。因此,本道题目的时间复杂度为\(\Theta(n\times \sum\limits_{i=1}^{n}a[i]/2)\),约为\(O(n^2)\)

参考代码:

参考代码在01背包的基础上进行了内存优化,将二维dp数组转换成了一维dp数组。其中:

  1. arr[i] 表示第i个员工的技能水平。
  2. sum 表示所有员工技能水平之和。
#include <iostream>
#include <cmath>
using namespace std;

int n, sum;
int arr[5005], dp[100005];

int main(){
    cin >> n;
    for (int i=1; i<=n; i++) {
        cin >> arr[i];
        sum += arr[i];
    }
    int half = sum / 2;
    for (int i=1; i<=n; i++){
        for (int j=half; j>=0; j--){
            if (j - arr[i] >= 0){
                dp[j] = max(dp[j], dp[j-arr[i]] + arr[i]);
            }   
        }
    }
    cout << sum - 2*dp[half] << endl;
    return 0;
}
posted @ 2024-03-18 09:01  Macw  阅读(14)  评论(0编辑  收藏  举报