(笔试题)将数组分成两组,使两组的和的差的绝对值最小
题目:
比如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];
}
运行结果:
(笔试题)将数组分成两组,使两组的和的差的绝对值最小相关推荐
- 2n个整数分为两组,使两组和差的绝对值最小
http://blog.sina.com.cn/s/blog_6f194ed3010114vt.html 最近建模看到作业这个题,一开始想了很久.在网上发现竟然没有完备的算法.不过最后想到一个可以Li ...
- LeetCode简单题之通过翻转子数组使两个数组相等
题目 给你两个长度相同的整数数组 target 和 arr . 每一步中,你可以选择 arr 的任意 非空子数组 并将它翻转.你可以执行此过程任意次. 如果你能让 arr 变得与 target 相同, ...
- C练题笔记之:Leetcode-1460. 通过翻转子数组使两个数组相等
题目: 给你两个长度相同的整数数组 target 和 arr . 每一步中,你可以选择 arr 的任意 非空子数组 并将它翻转.你可以执行此过程任意次. 如果你能让 arr 变得与 target 相同 ...
- 数组分成两组差值最小 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 ...
- 用php求n个分数的和,php关于数组n个随机数分成x组,使每组值相近的算法
主要原理是,将数组从大到小排序,数组1先取数取第一个,数组2第2取第2个,以此类推 取完第一次数组之后,判断下数组1,数组2,进行一次排序,将数据最大的排前面(理论上来说,数组1数据最大,因为从大到小 ...
- 58同城笔试题:数组去重;分饼干(分糖果);最小路径和(leetcode64)
1. 数组去重 题目描述 /*** 有序数组去重* 输出最终的数字个数* 输入:1,2,2* 输出:2* @author Turing**/ 代码 import java.util.*; public ...
- 招商:笔试题(数组统计重复次数,面包累计问题)
1. 数组统计重复次数 /*** @author Turing* 给定一个长度为N的数组,其元素取值范围是[1,N],统计数组中重复元素和重复次数* 要求时间复杂度是O(N),空间复杂度是O(1)*/ ...
- (笔试题)不用除法操作符,实现两个整数的除法
题目: 如题所示 思路: 与上一题要求不一样的是,这里是整数的除法,而不仅仅是正整数,因此需要对输入的两个数的正负性进行判断 代码: #include <iostream>using na ...
- php将数组值用 分开,PHP将数组分成基于相等值的组
我有一个Array包含2个值的数组,第一个是作者的编号,第二个是他的隶属关系. Array ( [0] => Array ( [0] => 2 [1] => Department o ...
最新文章
- 华为公有云架构解决方案
- linux 有线网卡,linux下有线网卡出现ADDRCONF(NETDEV_UP): eth0: link is not ready的解决方法...
- 怎么用matlab画TM11,矩形波导TM11模matlab仿真
- python编程书籍1020python编程书籍_代写INFT 1020作业、Database作业代做、Java课程作业代写、c++,Python编程作业代做...
- C++ | C++实现高精度加法——数组加法(附源代码)
- 真香!原来 CLI 开发可以这么简单
- 贵州大学 c语言,贵州大学C语言 试卷.doc
- python windows系统管理_利用Python脚本管理Windows服务
- 《魔兽世界插件》教程---21点扑克游戏 Blackjack
- 游戏筑基开发之单链表及其增删改查(C语言)
- IDEA+MAVEN+testNG(reportNG)
- java计算机毕业设计化妆品销售网站MyBatis+系统+LW文档+源码+调试部署
- 论“无常,苦、无我”
- 头条python后台一面凉经
- 1078 字符串压缩与解压
- 《C程序设计语言》笔记 第6章 结构
- oracle 导出dmp 文件 闪退 plsql
- 使用网络调试助手连接阿里云平台
- Spring Ioc容器,基于xml的bean管理
- 软件配置管理SCM和版本控制系统(VCS)