正经题解|来自领导的烦恼
2024-03-22 10:56:17
发布于:浙江
83阅读
0回复
0点赞
题目解析
本题可以使用动态规划或递归的方式来实现,本质上是一道01背包的变型题。假设一共有名员工,每一位员工的技能水平用表示。要使得两个部门的员工技能总和之差最小,意思就是尽可能地将一个部门的技能之和”凑“到,也就是所有员工技能总和的一半。套用背包问题的模板,每一位员工就是每一件“物品”,背包的容量就是“所有员工技能总和的二分之一”。
AC代码
参考代码在01背包的基础上进行了内存优化,将二维dp数组转换成了一维dp数组。其中:
arr[i]
表示第i个员工的技能水平。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;
}
时间复杂度分析
本题通过两个for
循环来填写dp表格,外层循环遍历每一个员工,内层循环遍历所有员工的技能水平之和。外层循环执行 次,内层循环执行 次。因此,本道题目的时间复杂度为 ,为 。
这里空空如也
有帮助,赞一个