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. Shanghai Regional Online Contest 1004

    Shanghai Regional Online Contest 1004 In the ACM International Collegiate Programming Contest, each ...

  2. Thank you for your resubmission. Performance - 2.3.10 We noticed that your app or its metadata includes irrelevant third-party platform information. Specifically, Android logo is mentioned in the

    被拒很多次,各种修改,最后发现是提交的时候,含有安卓的图标!欲哭无泪呀! Thank you for your resubmission. Performance - 2.3.10 We notice ...

  3. VS2013 Community配置OpenCV3.0.0

    配置环境:32位win7系统+VS2013 Community版本 1.首先从OpenCV官网上下载最新版本的OpenCV for Windows. 2.直接双击打开下载得到的opencv-3.0.0 ...

  4. 传统BIOS+UEFI 系统引导修复

    一.    去网上下载一款pe软件:BIOS+UEFI引导修复工具这个软件支持传统bios和最新的UEFI引导(1)进入PE环境(win也可以,不过引导损坏一般不能进win),打开软件         ...

  5. 使用liunx部署的心得

    安装SSH. 输入IP,输入用户名,点击连接,再输入密码. 如果采用的tomcat容器,则: 第一步: 查看正在运行的tomcat ps aux|grep tomcat 如果输出信息很长代表启动了的, ...

  6. C# switch

    要开学了(啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊) 做个沉默的行动者吧!(嘘嘘嘘嘘嘘嘘)今天去水题发现好多基础都不知道啊 1.   switch(控制语句) { case 常量表达式:{statement ...

  7. [BZOJ1503][NOI2004]郁闷的出纳员

    [BZOJ1503][NOI2004]郁闷的出纳员 试题描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是 ...

  8. (备忘)android清单文件中<meta-data>标签,以及<intent-filter>下的<data>标签及其他标签

    1.metadata可以写在application下也可以写在activity下,作为全局或activity内共享的数据 以键值对形式保存 <meta-data android:name=&qu ...

  9. linux下的/dev/shm目录

    linux下的/dev/shm目录 linux中/dev目录下一般都是一些设备文件,例如磁盘.内存.摄像头等. /dev/shm这个目录是linux下一个利用内存虚拟出来的一个目录,这个目录中的文件都 ...

  10. Android 手势水平监听判断

    package com.zihao.ui; import com.zihao.R; import android.os.Bundle; import android.app.Activity; imp ...