题目:

数组中的数分为两组,给出一个算法,使得两个组的和的差的绝对值最小数组中的数的取值范围是0<x<100,元素个数也是大于0,小于100
比如a[]={2,4,5,6,7},得出的两组数{2,4,,6}和{5,7},abs(sum(a1)-sum(a2))=0; 
比如{2,5,6,10},abs(sum(2,10)-sum(5,6))=1,所以得出的两组数分别为{2,10}和{5,,6}。

思路:

初看问题,感觉好像是个组合问题,通过暴力穷举解决问题。

但仔细想想,问题可以转换成,从数组中找出一组数据,使之尽可能等于数组和的一半。

这样一来是不是有点类似于0-1背包呢?是的,就是0-1背包问题。

条件:数组中的数就是背包问题的weight值,数组中的数也是背包问题的value值,即二者一样。

问题:背包里装哪些物品,使得其价值之和最接近总价值的一半。

于是通过背包问题来解决这道题就显得很简单了,下面简单陈述通过动态规划来求解0-1背包问题的思路。

假设V[i][j]表示从i件物品中选出重量为j的物品的最大价值,weight[i],value[i]分别代表第i件物品的重量和价值(在题目中,weight、value属于同一数组)。

动态转移方程为:

V[i][j]=V[i-1][j]  if j<weight[i]

V[i][j]=max(V[i-1][j],V[i-1][j-weight[i]]+value[i]) if j>weight[i]

另外,如果想知道是由那几件物品组成的最大价值,可以从后往前回溯,当V[i][j]>V[i-1][j],说明第i件物品被加入(路径不唯一)。

代码:

#include <iostream>
#include <vector>using namespace std;int knapSack(int num,int C,const vector<int> weight,const vector<int> value,vector<int> &x);int main()
{int w[]={2,4,5,6,7};int v[]={2,4,5,6,7};int num=sizeof(w)/sizeof(w[0]);vector<int> weight(w,w+num);vector<int> value(v,v+num);int C=12;vector<int> x(num);int total=knapSack(num,C,weight,value,x);cout<<"Total weight is "<<total<<endl;return 0;
}int knapSack(int num,int C,const vector<int> weight,const vector<int> value,vector<int> &x){vector<vector<int> > V(num+1,vector<int>(C+1));for(int i=1;i<=num;i++){for(int j=1;j<=C;j++){if(j<weight[i-1])V[i][j]=V[i-1][j];elseV[i][j]=max(V[i-1][j],V[i-1][j-weight[i-1]]+value[i-1]);}}cout<<"Dynamic Matrix: "<<endl;for(int i=1;i<=num;i++){for(int j=1;j<=C;j++){cout<<V[i][j]<<" ";}cout<<endl;}int j=C;for(int i=num;i>0;i--){if(V[i][j]>V[i-1][j]){x[i]=1;j=j-weight[i-1];}elsex[i]=0;}cout<<"The articles chosen is: "<<endl;for(int i=0;i<num;i++){if(x[i])cout<<i+1<<" ";}cout<<endl;return V[num][C];
}

运行结果:

(笔试题)将数组分成两组,使两组的和的差的绝对值最小相关推荐

  1. 2n个整数分为两组,使两组和差的绝对值最小

    http://blog.sina.com.cn/s/blog_6f194ed3010114vt.html 最近建模看到作业这个题,一开始想了很久.在网上发现竟然没有完备的算法.不过最后想到一个可以Li ...

  2. LeetCode简单题之通过翻转子数组使两个数组相等

    题目 给你两个长度相同的整数数组 target 和 arr . 每一步中,你可以选择 arr 的任意 非空子数组 并将它翻转.你可以执行此过程任意次. 如果你能让 arr 变得与 target 相同, ...

  3. C练题笔记之:Leetcode-1460. 通过翻转子数组使两个数组相等

    题目: 给你两个长度相同的整数数组 target 和 arr . 每一步中,你可以选择 arr 的任意 非空子数组 并将它翻转.你可以执行此过程任意次. 如果你能让 arr 变得与 target 相同 ...

  4. 数组分成两组差值最小 python_数组中的数分为两组,让给出一个算法,使得两个组的和的差的绝对值最小,数组中的数的取值范围是0x100,元素个数也是大于0, 小于100 。...

    比如a[]={2,4,5,6,7},得出的两组数{2,4,6}和{5,7},abs(sum(a1)-sum(a2))=0: 比如{2,5,6,10},abs(sum(2,10)-sum(5,6))=1 ...

  5. 用php求n个分数的和,php关于数组n个随机数分成x组,使每组值相近的算法

    主要原理是,将数组从大到小排序,数组1先取数取第一个,数组2第2取第2个,以此类推 取完第一次数组之后,判断下数组1,数组2,进行一次排序,将数据最大的排前面(理论上来说,数组1数据最大,因为从大到小 ...

  6. 58同城笔试题:数组去重;分饼干(分糖果);最小路径和(leetcode64)

    1. 数组去重 题目描述 /*** 有序数组去重* 输出最终的数字个数* 输入:1,2,2* 输出:2* @author Turing**/ 代码 import java.util.*; public ...

  7. 招商:笔试题(数组统计重复次数,面包累计问题)

    1. 数组统计重复次数 /*** @author Turing* 给定一个长度为N的数组,其元素取值范围是[1,N],统计数组中重复元素和重复次数* 要求时间复杂度是O(N),空间复杂度是O(1)*/ ...

  8. (笔试题)不用除法操作符,实现两个整数的除法

    题目: 如题所示 思路: 与上一题要求不一样的是,这里是整数的除法,而不仅仅是正整数,因此需要对输入的两个数的正负性进行判断 代码: #include <iostream>using na ...

  9. php将数组值用 分开,PHP将数组分成基于相等值的组

    我有一个Array包含2个值的数组,第一个是作者的编号,第二个是他的隶属关系. Array ( [0] => Array ( [0] => 2 [1] => Department o ...

最新文章

  1. 华为公有云架构解决方案
  2. linux 有线网卡,linux下有线网卡出现ADDRCONF(NETDEV_UP): eth0: link is not ready的解决方法...
  3. 怎么用matlab画TM11,矩形波导TM11模matlab仿真
  4. python编程书籍1020python编程书籍_代写INFT 1020作业、Database作业代做、Java课程作业代写、c++,Python编程作业代做...
  5. C++ | C++实现高精度加法——数组加法(附源代码)
  6. 真香!原来 CLI 开发可以这么简单
  7. 贵州大学 c语言,贵州大学C语言 试卷.doc
  8. python windows系统管理_利用Python脚本管理Windows服务
  9. 《魔兽世界插件》教程---21点扑克游戏 Blackjack
  10. 游戏筑基开发之单链表及其增删改查(C语言)
  11. IDEA+MAVEN+testNG(reportNG)
  12. java计算机毕业设计化妆品销售网站MyBatis+系统+LW文档+源码+调试部署
  13. 论“无常,苦、无我”
  14. 头条python后台一面凉经
  15. 1078 字符串压缩与解压
  16. 《C程序设计语言》笔记 第6章 结构
  17. oracle 导出dmp 文件 闪退 plsql
  18. 使用网络调试助手连接阿里云平台
  19. Spring Ioc容器,基于xml的bean管理
  20. 软件配置管理SCM和版本控制系统(VCS)

热门文章

  1. python中文字符编码问题
  2. API设计中防重放攻击
  3. Kotlin的2017年总结与2018年展望
  4. jquery可见性选择器(匹配匹配所有显示的元素)
  5. Objective-C之成魔之路【16-使用文件】
  6. SEO和Social工具.doc
  7. MySQL Workbench 5.2.45 GA 发布
  8. Eclipse-配置workspace路径
  9. 一笔画问题 连通图(搜索+队列)
  10. 拓扑排序--关键路径