社区
数据结构与算法
帖子详情
把一组长度为偶数数列,平均分成2组,怎样分使得|sum(a)-sum(b)|最小。
babykick
2011-07-12 03:51:29
如题:
把一组长度为偶数数列,平均分成2组a和b,怎样分使得|sum(a)-sum(b)|最小。
直觉上似乎要用到DP,用子序列求解,但是感觉子问题和状态转移不好定义,n到n+1的归纳不好搞。
哪位有好的DP解法?当然不是DP的也行。
...全文
332
10
打赏
收藏
把一组长度为偶数数列,平均分成2组,怎样分使得|sum(a)-sum(b)|最小。
如题: 把一组长度为偶数数列,平均分成2组a和b,怎样分使得|sum(a)-sum(b)|最小。 直觉上似乎要用到DP,用子序列求解,但是感觉子问题和状态转移不好定义,n到n+1的归纳不好搞。 哪位有好的DP解法?当然不是DP的也行。
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
10 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
超级大笨狼
2011-07-20
打赏
举报
回复
平均分成2组a和b?
这个题目用DP不需要,就是两贼分赃的例子.
排序后,O(n)分一次,使得前半后半差值Delt小于分界点后边的值.
O(n/2)得到前半小于差值Delt的最大值,加后半去.
重复,直到无数可找
重复部分复杂度是收敛的,最坏找n/2次
总体是O(n*lgn)
ljsspace
2011-07-14
打赏
举报
回复
楼上的, 这里有个反例:
{1,2,3,4,40,98,99,100}。
icessl
2011-07-13
打赏
举报
回复
更正一下:
if (t>=n || 在 Flag[0..t-1] 中已有 n/2 个 1)
{
把Flag[t..n-1]都置成 0;
......
改为
if (t>=n || 在 Flag[0..t-1] 中已有 n/2 个 1 || 在 Flag[0..t-1] 中已有 n/2 个 0)
{
根据 Flag[0..t-1] 中1的个数 把Flag[t..n-1]都置成 0或 1;
.........
icessl
2011-07-13
打赏
举报
回复
该问题不是子集和问题,因为本问题对子集元素个数有限制,只能是n/2.所以,用回溯法求解会方便一些.
char glbBestFlag[N]; // 最优向量,glbBestFlag[i]==0 表示第 i 元素在集合 a
// glbBestFlag[i]==1 表示第 i 元素在集合 b
int glbBestDet; // min(|sum(a)-sum(b)|)
// 初始就是原始集合所有元素绝对值之和
// 算法主体
// 入参: x[] 元素集合,x[0] 首元素 x[n-1] 末元素
// n 元素个数
// Flag[] 当前部分解 Flag[i]=0 表示x[i]在集合 a,否则在集合 b
// t 当前测试元素下标.初始值是 0
int SolveIt(int x[],int n,char Flag[],int t)
{
if (t>=n || 在 Flag[0..t-1] 中已有 n/2 个 1)
{
把Flag[t..n-1]都置成 0;
根据Flag[0..n-1]的内容计算 det=|sum(a)-sum(b)|;
if (det<glbBestDet) // 发现一个更优解
{
glbBestDet=det; // 记录该更优解
glbBestFlag[0..n-1]=Flag[0..n-1];
}
return 0;
}
Flag[t]=0;
SolveIt(x,n,Flag,t+1);
Flag[t]=1;
SolveIt(x,n,Flag,t+1);
return 0;
}
主调函数如下:
char Flag[N];
SolveIt(x,n,Flag,0);
返回时,glbBestDet就是min(|sum(a)-sum(b)|),glbBestFlag[0..n-1]就是解向量.
华芸智森
2011-07-13
打赏
举报
回复
排序.
如:100个数.
SUM(A)=SUM(1:25) +SUM(76:100)
SUM(B)=SUM(26:75)
babykick
2011-07-13
打赏
举报
回复
楼上的回溯法没有prune, 和穷举似乎没区别啊。
babykick
2011-07-12
打赏
举报
回复
谢谢楼上几位,让我获得不少启发。
ljsspace
2011-07-12
打赏
举报
回复
很早之前解过这个问题:
http://blog.csdn.net/ljsspace/article/details/6434621
xibeitianlang
2011-07-12
打赏
举报
回复
1、排序;
2、交叉优先权分配,1、4、5,。。。 2、3、6,。。。
3、调整。
例如1,2,3,4,5,10;
1+4+5=10; 2+3+10=15
1和3交换,3-1<(15-10)/2
3+4+5=12 2+1+10=13
cfvmario
2011-07-12
打赏
举报
回复
首先不可能有有效算法,不然不就解决子集和问题了么。
用C语言编写:有一个
长度
为n的
数列
,该
数列
定义为从2开始的递增有序
偶数
......
例题:有一个
长度
为n(n<=100)的
数列
,该
数列
定义为从2开始的递增有序
偶数
,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值。编程输出该平均值序列。#include<stdio.h> void main() { int n,m,i,j,
sum
=0,k; while(~scanf("%d%d",&n,&m))//读取操作 { ...
递增
偶数
数列
按顺序每m个求平均【C语言】
Description 有一个
长度
为n(n<=100)的
数列
,该
数列
定义为从2开始的递增有序
偶数
,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值。编程输出该平均值序列。 Input 输入数据有多
组
,每
组
占一行,包含两个正整数n和m,n和m的含义如上所述。 Output 对于每
组
输入数据,输出一个平均值序列,每
组
输出占一行。 Sample Inpu...
sum
A^B 等比
数列
求和(log(k))
题目地址 -> 一个方法,因为mod捕食不是质数。 poj 1845 -> 两个方法都可以 还有一个求逆元的解法参考以前博客 先化等比
数列
: 设
sum
= (1+q+…+qc) 假设 c为奇数, 则可以得到
sum
= (1+q+…+q(c/2)+q((c+1)/2)+…+qc) 则为
sum
= (1+q+…+q(c/2)+q((c+1)/2)*(1+q+…+q(c/2)))
sum
= (1+q((c+1)/2)) * (1+q+…+q(c/2)) 当 c 为
偶数
时,同理,
sum
= (
将数
组
分
成
两部
分
,使得这两部
分
的和的差
最小
将一个数
组
分
成
两部
分
,不要求两部
分
所包含的元素个数相等,要求使得这两个部
分
的和的差值
最小
。比如对于数
组
{1,0,1,7,2,4},可以
分
成
{1,0,1,2,4}和{7},使得这两部
分
的差值
最小
。思路:这个问题可以转化为求数
组
的一个子集,使得这个子集中的元素的和尽可能接近
sum
/2,其中
sum
为数
组
中所有元素的和。这样转换之后这个问题就很类似0-1背包问题了:在n件物品中找到m件物品,他们的可以装入背
偶数
求和 (2021-7-21)
偶数
求和 题目链接 有一个
长度
为n(n<=100)的
数列
,该
数列
定义为从2开始的递增有序
偶数
,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值。编程输出该平均值序列。 Input 输入数据有多
组
,每
组
占一行,包含两个正整数n和m,n和m的含义如上所述。 Output 对于每
组
输入数据,输出一个平均值序列,每
组
输出占一行。 Sample Input 3 2 4 2 Sample Output 3 6 3 7 提交次数:2次 坑点:如果最后不足m个,则以实际数量求平均值,理
数据结构与算法
33,027
社区成员
35,336
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章