【编程题目】有两个序列 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( ...
随机推荐
- 密码学初级教程(一)基本概念及DES加密算法
密码技术在网络通信中广泛使用,本节是初步接触密码学技术的笔记. 第1章 加密-解密 破译 明文-密文 密钥 密码算法 对称密码-公钥密码(非对称密码) 单向散列函数-散列值 消息认证码 数字签名 伪随 ...
- jQuery属性选择器.attr()和.prop()两种方法
在判断表单单选框是否被选中时,通常会想到使用$('#checkbox').attr('checked')来判断,但在一些情况下,你会发现这种方法并不管用,得到的是undefined. 原来jQuery ...
- WCF中安全的那些事!!!
WCF默认绑定 WCF预先为所有绑定都定义了能满足大多数情形的配置模式,这样的话,只要没有修改某个配置参数,WCF就使用默认的安全模式. 先上一张默认的安全设置表格 绑定 设置 wsHttpBindi ...
- 湖南国庆模拟赛day1 分组
题目大意:给你一个n个数的数列s,要对这些数进行分组,当有任意两个数在一种方案在一起而在另一种方案中不在一起算是两种不同的方案,一个组的"不和谐程度"为组内数的极差,如果只有一个人 ...
- [C++基础]关于对象的创建及内存分配
测试: #include <stdio.h>#include <QDebug> class KPoint{public: KPoint(int x, int y){ nx = ...
- Cotex-M3内核STM32F10XX系列时钟及其配置方法
一.背景 最近做个项目,需要使用STM32,还是以前一样的观点,时钟就是MCU心脏,供血即时钟频率输出,想要弄明白一个MCU,时钟是一个非常好的切入点.言归正传,网上已经有太多大神详述过STM32的详 ...
- Hdu.1325.Is It A Tree?(并查集)
Is It A Tree? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- bootstrap-collapse
colapse插件:折叠功能 插件:collapse.js 实现方法:以data-toggle做被点击者,以div class="collapse in"显示展开内容 <sc ...
- C++中的内联成员函数与非内联成员函数
在C++中内联成员函数与非内联成员函数的可以分为两种情况: 1.如果成员函数的声明和定义是在一起的,那么无论有没有写inline这个成员函数都是内联的,如下: using namespace std; ...
- HDU 2795
题目: http://acm.hdu.edu.cn/showproblem.php?pid=2795 线段树问题,线段树的每个叶子节点保存的是当前行还剩余的长度,每次查询找到满足条件的一行减去该条幅的 ...