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,序列元素的值任意整数,无序;(需要回头仔细研究)的更多相关文章

  1. 编程题目: 两个队列实现栈(Python)

    感觉两个队列实现栈 比 两个栈实现队列 麻烦 1.栈为空:当两个队列都为空的时候,栈为空 2.入栈操作:当队列2为空的时候,将元素入队到队列1:当队列1位空的时候,将元素入队到队列2: 如果队列1 和 ...

  2. 有两个序列a,b,大小都为n,序列元素的值是任意整数,无序。

    要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小. 例如: var a=[100,99,98,1,2, 3]; var b=[1, 2, 3, 4,5,40]. in ...

  3. 有两个数组a,b,大小都为n,;通过交换a,b中的元素,使sum(a)-sum(b)最小。

    有两个数组a,b,大小都为n,数组元素的值任意整形数,无序: 要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小. 当前数组a和数组b的和之差为    A = sum(a) - ...

  4. OJ——华为编程题目:输入字符串括号是否匹配

    package t0815; /* * 华为编程题目:输入字符串括号是否匹配 * 若都匹配输出为0,否则为1 * 样例输入:Terminal user [name | number (1)] * 样例 ...

  5. 【编程题目】栈的 push、pop 序列

    29.栈的 push.pop 序列(栈)题目:输入两个整数序列.其中一个序列表示栈的 push 顺序,判断另一个序列有没有可能是对应的 pop 顺序.为了简单起见,我们假设 push 序列的任意两个整 ...

  6. 关于C语言的几个考试编程题目

    提交要求:1:邮件名称:学号后三位-题目编号-姓名-期中考试.例如:098-1-沈苗-期中考试2:不用附件提交,直接写邮件,内容包括编程思路(写一段自己对题目的认识.思路.技术细节等).源代码.运行结 ...

  7. 剑指offer算法编程题目部分汇总(解法略)

    总结一下本书中遇到的大部分面试题.面试题3:二维数组中的查找 题目:在一个二维数组中,每一行都按照从左到右的递增顺序排列,每一列都按照从上到下递增的顺序排列,请完成一个函数,输入这样的一个整数,判断数 ...

  8. 网易云课堂_C++程序设计入门(下)_期末考试_期末考试在线编程题目

    期末考试在线编程题目 返回考试   本次考试题目一共两个,在考试期间可以不限制次数地提交 温馨提示: 1.本次考试属于Online Judge题目,提交后由系统即时判分. 2.学生可以在考试截止时间 ...

  9. 赠书:HTML5 Canvas 2d 编程必读的两本经典

    赠书:HTML5 Canvas 2d 编程必读的两本经典 这两年多一直在和HTML5 Canvas 打交道,也带领团队开发了世界首款基于HTML5 Canvas 的演示文档工具---AxeSlide( ...

随机推荐

  1. 2015年11月26日 Java基础系列(一)之String与StringBuffer与StringBuilder的区别

    序,StringBuffer是线程安全的,StringBuilder是线程不安全的,但是StringBuilder操作速度快,因此在使用时要根据场景合理选择. StringBuffer和StringB ...

  2. 包介绍 - Fluent Validation (用于验证)

    Install-Package FluentValidation 如果你使用MVC5 可以使用下面的包 Install-Package FluentValidation.MVC5 例子: public ...

  3. Todd's Matlab讲义第4讲:控制误差和条件语句

    误差和残量 数值求解方程\(f(x)=0\)的根,有多种方法测算结果的近似程度.最直接的方法是计算误差.第\(n\)步迭代结果与真值\(x^\*\)的差即为第\(n\)步迭代的误差: \begin{e ...

  4. TP3.1 中URL和APP区别

    1.__URL__指当前模块地址,就是当前的action的地址.(每个__action都是一个模块)    eg:当前打开config.html,那么config.html里边的__URL__/sav ...

  5. eclipse svn快捷键

    一.打开eclipse插件安装市场,搜索svn,选择Subclipse安装 二.设置 svn ,设置快捷键, 1.windows-preference,在打开对话框输入keys过滤出keys选择 2. ...

  6. Android在TextView中实现RichText风格

    参考: Android实战技巧:用TextView实现Rich Text---在同一个TextView中设置不同的字体风格 Demo: private SpannableStringBuilder c ...

  7. 如何在CentOS 7上安装EPEL源

    EPEL 是什么? EPEL (Extra Packages for Enterprise Linux,企业版Linux的额外软件包) 是Fedora小组维护的一个软件仓库项目,为RHEL/CentO ...

  8. CMake Error: your CXX compiler: "" was not found

    [root@amax src]# cmake . -- The CXX compiler identification is unknown CMake Error at /usr/local/sha ...

  9. python 集合 -----直接用逗号连接的是元组,不是list

    t = 12345, 54321, 'hello!' >>> t[0] 12345 >>> t (12345, 54321, 'hello!') 元组:元组由逗号分 ...

  10. 如何用C语言编写病毒‘

    怎样用C语言编写病毒在分析病毒机理的基础上,用C语言写了一个小病毒作为实例,用TURBOC2.0实现.[Abstract] This paper introduce the charateristic ...