【编程题目】有两个序列 a,b,大小都为 n,序列元素的值任意整数,无序;(需要回头仔细研究)
32.(数组、规划)
有两个序列 a,b,大小都为 n,序列元素的值任意整数,无序;
要求:通过交换 a,b 中的元素,使[序列 a 元素的和]与[序列 b 元素的和]之间的差最小。
例如:
var a=[100,99,98,1,2,3];
var b=[1,2,3,4,5,40];
首先,目标一定是先找到n个数字,使得数字和比总和的一半小,但是最接近。
思路一:开始看这道题跟之前学的动态规划很像,就想用动态规划来解。但是....做不出来........... 必须要选一半的数字让我头都大了。
思路二:接着想写递归,就是把a, b(各n个)中的数字都放在 c 中,选一半的数字n个那就可以分为:
1.选入最后一个数字 第2n - 1个,在剩下的数字中选择其他 n - 1个数字
2.不选入最后一个数字, 在剩下的数字中选择 n个数字
这样,递归的思路就有了。
可是在怎么把得到的结果传出来上面我又犯了难,每个数字都是一层层递归选的,怎么传出来啊?? 好了,到这里卡死了......
void choose(int * c, int len, int N, int sum) //N是要从中挑选几个数字
{
static int sumtmax = ;
static int sumt = ;
static int num = ;
if(len < N)
{
return;
}
if(N == )
{
if(sumt <= sum/ && sumt > sumtmax)
{
sumtmax = sumt;
}
printf("%d : %d %d\n", ++num, sumt, sumtmax);
return;
} choose(c, len - , N, sum); sumt += c[len - ];
choose(c, len - , N - , sum);
sumt -= c[len - ];
} void exchange(int * a, int * b, int len)
{
int * c = (int *)malloc( * len * sizeof(int));
int * smaller = (int *)malloc(len * sizeof(int));
int sum = ;
for(int i = ; i < len; i++)
{
c[i] = a[i];
sum += a[i];
}
for(int i = ; i < len; i++)
{
c[i + len] = b[i];
sum += b[i];
} choose(c, len * , len, sum); }
思路三:和12个人排两列的思路相同。用二进制 用数字i 从0 - (1 << 2 * n)的范围变化, 其二进制中的1,就表示数字选入a, 我们遍历所有的可能找到a中的和最接近总和一半的组合。再另外用一个数字保存最接近时的分布就好了。
不过这样的写法一个很不好的限制就是int的位数是有限的,只有64位,也就是说n大于32时我的方法就失效了
/*
32.(数组、规划)
有两个序列 a,b,大小都为 n,序列元素的值任意整数,无序;
要求:通过交换 a,b 中的元素,使[序列 a 元素的和]与[序列 b 元素的和]之间的差最小。
例如:
var a=[100,99,98,1,2,3];
var b=[1,2,3,4,5,40];
*/ #include<stdio.h>
#include<stdlib.h>
#include<string.h> int bit_c(int n) //统计n的二进制表达中有几个1
{
int result = ;
for(; n; n &= n-, result++);
return result;
} void exchange2(int * a, int * b, int len)
{
int * c = (int *)malloc( * len * sizeof(int));
int * smaller = (int *)malloc(len * sizeof(int));
int sum = ;
for(int i = ; i < len; i++)
{
c[i] = a[i];
sum += a[i];
}
for(int i = ; i < len; i++)
{
c[i + len] = b[i];
sum += b[i];
} int maxsumh = ;
int mask = ;
for(int i = ; i < ( << len * ); i++)
{
if(bit_c(i) == len)
{
int sumhalf = ;
for(int j = ; j < len * ; j++)
{
if(((i >> j) & ) == )
{
sumhalf += c[j];
}
}
if(sumhalf <= sum / && sumhalf > maxsumh)
{
maxsumh = sumhalf;
mask = i;
}
}
} int ai = , bi = ;
for(int j = ; j < len * ; j++)
{
if(((mask >> j) & ) == )
{
a[ai++] = c[j];
}
else
{
b[bi++] = c[j];
}
} printf("最小差值为:%d", sum - * maxsumh); free(c); } int main()
{
int a[] = {,,,,};
int b[] = {, , , , };
exchange2(a, b, );
return ;
}
网上有各种解法:
http://blog.csdn.net/tianshuai1111/article/details/7479767 中提出了两种。
但其中一种被http://blog.csdn.net/cwqbuptcwqbupt/article/details/7521733 用反例否决了。
http://blog.csdn.net/ljsspace/article/details/6434621# 中用到了回溯法 但评论中说存在问题 我还没仔细看
【编程题目】有两个序列 a,b,大小都为 n,序列元素的值任意整数,无序;(需要回头仔细研究)的更多相关文章
- 编程题目: 两个队列实现栈(Python)
感觉两个队列实现栈 比 两个栈实现队列 麻烦 1.栈为空:当两个队列都为空的时候,栈为空 2.入栈操作:当队列2为空的时候,将元素入队到队列1:当队列1位空的时候,将元素入队到队列2: 如果队列1 和 ...
- 有两个序列a,b,大小都为n,序列元素的值是任意整数,无序。
要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小. 例如: var a=[100,99,98,1,2, 3]; var b=[1, 2, 3, 4,5,40]. in ...
- 有两个数组a,b,大小都为n,;通过交换a,b中的元素,使sum(a)-sum(b)最小。
有两个数组a,b,大小都为n,数组元素的值任意整形数,无序: 要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小. 当前数组a和数组b的和之差为 A = sum(a) - ...
- OJ——华为编程题目:输入字符串括号是否匹配
package t0815; /* * 华为编程题目:输入字符串括号是否匹配 * 若都匹配输出为0,否则为1 * 样例输入:Terminal user [name | number (1)] * 样例 ...
- 【编程题目】栈的 push、pop 序列
29.栈的 push.pop 序列(栈)题目:输入两个整数序列.其中一个序列表示栈的 push 顺序,判断另一个序列有没有可能是对应的 pop 顺序.为了简单起见,我们假设 push 序列的任意两个整 ...
- 关于C语言的几个考试编程题目
提交要求:1:邮件名称:学号后三位-题目编号-姓名-期中考试.例如:098-1-沈苗-期中考试2:不用附件提交,直接写邮件,内容包括编程思路(写一段自己对题目的认识.思路.技术细节等).源代码.运行结 ...
- 剑指offer算法编程题目部分汇总(解法略)
总结一下本书中遇到的大部分面试题.面试题3:二维数组中的查找 题目:在一个二维数组中,每一行都按照从左到右的递增顺序排列,每一列都按照从上到下递增的顺序排列,请完成一个函数,输入这样的一个整数,判断数 ...
- 网易云课堂_C++程序设计入门(下)_期末考试_期末考试在线编程题目
期末考试在线编程题目 返回考试 本次考试题目一共两个,在考试期间可以不限制次数地提交 温馨提示: 1.本次考试属于Online Judge题目,提交后由系统即时判分. 2.学生可以在考试截止时间 ...
- 赠书:HTML5 Canvas 2d 编程必读的两本经典
赠书:HTML5 Canvas 2d 编程必读的两本经典 这两年多一直在和HTML5 Canvas 打交道,也带领团队开发了世界首款基于HTML5 Canvas 的演示文档工具---AxeSlide( ...
随机推荐
- 2015年12月01日 GitHub入门学习(二)手把手教你Git安装
序:Mac与Linux中,Mac都预装了Git,各版本的Linux也都提供了Git的软件包.下面手把手教你Windows下的安装. 一.Git Windows GUI 下载地址 msysgit htt ...
- R笔记 map_leaflet googlevis
packages : map leaflet library(leaflet) library(maps) mapStates = map("state", fill = TRUE ...
- 重温javascript事件机制
以前用过一段时间的jquery感觉太方便,太强大了,各种动画效果,dom事件.创建节点.遍历.控件及UI库,应有尽有:开发文档也很多,网上讨论的问题更是甚多,种种迹象表明jquery是一个出色的jav ...
- HDOJ 1576 A/B
数论水题... A/B Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- ASN.1编码
来自几年前本人写的一篇博客 http://blog.csdn.net/newyf_cun/article/details/13016069 如下使用libtasn1分析asn1的编码规则. http: ...
- codeblocks+Mingw 下配置开源c++单元测试工具 google test
google test 是google的c++开源单元测试工具,chrome的开发团队就是使用它. Code::Blocks 12.11(MinGW 4.7.1) (Windows版)Google T ...
- 【转】 js怎么区分出点击的是鼠标左键还是右键?
IE 下 onMouseDown 事件有个 events.button 可以返回一个数值,根据数值判断取得用户按了那个鼠标键 events.button==0 默认.没有按任何按钮. events. ...
- UDS帧传输
说明 在UDS协议中,其中有一点我视作为基础,即帧传输.也即是数据传输这一块,在UDS的帧传输中,分为4种: SF单帧 FF第一帧 CF连续帧 FC流控制帧 首先,我们抛开以上的东西,假设一个销售商( ...
- NOI2009 诗人小G
Sol 决策单调性+二分 传说中的四边形不等式...其实做了这道题还是不会... 证明简直吃屎//// 贴个传送门这里有部分分做法还有决策单调性的证明 byvoid ISA tell me that ...
- 12 哈希表相关类——Live555源码阅读(一)基本组件类
12 哈希表相关类--Live555源码阅读(一)基本组件类 这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 ...