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. [译]Mongoose指南 - 查询

    查询有带callback和不带callback两种方式 所有mongoose的callback都是这种格式: callback(err, result) var Person = mongoose.m ...

  2. MYSQL基础语句

    参考书籍< MySQL数据库基础与实例教程> --孔祥盛 SQL(structured query language)结构化查询语言,应用最为广泛的关系型数据库语言. MYSQL属于关系型 ...

  3. css3 github javascript

    欢迎关注我的 github github博客地址 github地址

  4. JavaScript获取onclick、onchange等事件值的代码

    这里主要是用到了getAttributeNode()这个方法,它获取的是属性节点,忽略属性和事件的差别,具体示例如下,感兴趣的朋友可以参考下哈希望对大家有所帮助 今天小菜处理下拉菜单级联问题时,想获取 ...

  5. Sqli-LABS通关笔录-7[文件写入函数Outfile]

    该关卡最主要的就是想要我们学习到Outfile函数(文件写入函数)的使用. 通过源代码我们很容易的写出了payload.倘若我们一个个去尝试的话,说实话,不容易. http://127.0.0.1/s ...

  6. ZUI前段框架简介

    一.说明 基于Bootstrap定制 ZUI继承了Bootstrap 3中的大部分基础内容,但出于与Bootstrap不同的目的,一些组件都进行了定制和修改.这些变化包括: 移除了部分插件的限制,增加 ...

  7. poj3984

    定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, ...

  8. Laplacian matrix 从拉普拉斯矩阵到谱聚类

    谱聚类步骤 第一步:数据准备,生成图的邻接矩阵: 第二步:归一化普拉斯矩阵: 第三步:生成最小的k个特征值和对应的特征向量: 第四步:将特征向量kmeans聚类(少量的特征向量):

  9. PyQt4 QListview控件使用方法

    1.往QListView控件内写入数据 strlist=QStringList()strlist.append('hello')strm=QStringListModel(strlist)self.u ...

  10. uniq命令注意事项,检查重复行的时候,只会检查相邻的行。

    今天在使用uniq命令统计数量时,uniq -c总是得不到想要的效果,相同的行没有合并,例如 后来在http://ju.outofmemory.cn/entry/78365才看到,原来uniq检查重复 ...