编程之美读书笔记-数组分割
来源:互联网 发布:编程麻将机 编辑:程序博客网 时间:2024/05/24 05:38
题目:有一个没有排序,元素个数为2n的正整数数组。要求把它分割为元素个数为n的两个数组,并使两个子数组的和最接近。
解析:一个直观的想法是先将数组中所有元素排序为a1<a2<a3……<a2N,将它们划分为两个子数组S1=a1,a3,a5……和S2=a2,a4,a6……。从S1和S2中找出一对数进行交换,使得它们之间的差值尽可能小,直到找不到可对换的。这种想法的缺陷是得到的S1和S2并不是最优的。假设2n个整数之和为SUM,从2n个整数中找出n个元素的和,有三种可能:大于SUM/2,等于SUM/2和小于SUM/2,可以只考虑小于等于SUM/2的情况。利用动态规划来解决这个问题。把任务分成2n步,第k步的定义是前k个元素中任意i个元素的和Sk。将第k步分拆为两小步,首先得到前k-1个元素中任意i个元素的和Sk-1,然后令Sk=Sk-1U{vi+arr[k]}。
#include<vector>#include<iostream>#include<algorithm>using namespace std;int n,arr[1000];int main(){cin >> n;for (int i = 1; i <= 2 * n; i++){cin >> arr[i];}int sum = 0;for (int i = 1; i <= 2 * n; i++){sum += arr[i];}vector<int> sums[100];//sums[i]表示从arr中取i个数所能产生的和的集合vector<int>::iterator it;sums[0].push_back(0);int i, j, i_max;for (i = 1; i <= 2 * n; i++){i_max = min(i - 1, n - 1);for (j = i_max; j >= 0; j--){for (it = sums[j].begin(); it != sums[j].end(); it++){sums[j + 1].push_back(arr[i] + *it);}}}int minval = sum;for (it = sums[n].begin(); it != sums[n].end(); it++){if (*it <= sum / 2){minval = min(minval, sum - *it*2);}}cout << minval << endl;return 0;}
这个算法的复杂度是指数级的,因此在n很大时效率很低。我们需要设计一个算法使得第k步所花费的时间与k无关。原来是给定Sk-1={vi}求Sk,那么也可以给定Sk的可能值v和arr[k],去寻找v-arr[k]是否在Sk-1={vi}中。
#include<vector>#include<iostream>#include<algorithm>using namespace std;int n,arr[1000],isok[100][1000];//isok[i][v]表示是否可以找到i个数使得它们和等于vint main(){cin >> n;for (int i = 1; i <= 2 * n; i++){cin >> arr[i];}int sum = 0;for (int i = 1; i <= 2 * n; i++){sum += arr[i];}isok[0][0] = 1;for (int k = 1; k <= 2 * n; k++){for (int i = min(k, n); i >= 1; i--){for (int v = 1; v <= sum / 2; v++){if (v >= arr[k] && isok[i - 1][v - arr[k]]){isok[i][v] = true;}}}}for (int v = sum / 2; v >= 0; v--){if (isok[n][v]){cout << sum - 2 * v << endl;break;}}return 0;}
0 0
- 编程之美读书笔记-数组分割
- 读书笔记之编程之美 - 2.18 数组分割
- 编程之美读书笔记_2.18 数组分割
- 《编程之美》读书笔记(四)——数组分割
- 编程之美读书笔记2.18—数组分割
- 编程之美 数组分割
- 编程之美-数组分割
- 《编程之美》数组分割
- 编程之美 - 数组分割
- 编程之美之数组分割
- 编程之美;数组分割DP;
- 《编程之美》 2.18 数组分割
- DP 数组分割《编程之美》
- 编程之美 2.18 数组分割
- 编程之美数组分割问题
- 编程之美2.18 数组分割
- 【编程之美】数组分割问题
- 《编程之美》 2.18 数组分割
- Javascript学习笔记(入门篇)
- [leetcode]74. Search a 2D Matrix
- 二分图的最大匹配、完美匹配和匈牙利算法
- 多线程的实现方案
- 数据结构实验之栈一:进制转换
- 编程之美读书笔记-数组分割
- 斯坦福公开课Machine Learning笔记(八)--Online Learning
- Android下开机启动后U盘经常不能自动挂载
- Deprecated: Assigning the return value of new by reference is deprecated in……解决方法
- Source Insight上手
- 搭建持续集成环境(Jenkins+GitHub+Xcode+fir)
- (Leetcode)backtracking回溯法 题目汇总
- 乘坐公交-(贪心算法)
- android 网络请求