算法--切割的数组


标题来源:编程之美2.18

有一个无序的,元素个数为2n的正整数的数组,要求:

怎样能把这个数组切割为元素个数为n的两个数组,使得两个子数组的和尽量接近。

解析:由于两个子数组的和是一定的,等于整个数组的和。如今要求使得两个字数组的和尽量的接近,也就意味着要从当中选出n个数使得这n个数的和尽可能的接近sum/2,最好还是设为从小于sum/2的方向接近。于是。这就是一个01背包的问题:

如今有2N个物品,每一个物品的重量为A[i],有一个背包的大小为sum/2,如今从中挑选出N个物品,使得背包尽可能的被装满。

于是定义递推式为:

dp[i][j][v] = max(dp[i-1][j][v], dp[i-1][j-1][v-A[i]]+A[i]);

dp[i][j][v] :从前i个物品中选择j个,重量不大于v的最大的和。

上述print部分是在打印当中的一个子数组。返回的是终于的两个数组的最小的差值。

时间复杂度为: O(N*N*sum)

拓展:假设上述代码仅仅是要求计算终于的差值,而不须要打印出结果数组的话。那么我们就能够将时间复杂度减少到N*sum.

代码为:

终于的结果是f[N][v]==true的最大的v的值即为所求。(v是从sum/2開始依次减小)。

版权声明:本文博主原创文章。博客,未经同意不得转载。

时间: 2024-10-22 19:54:27

算法--切割的数组的相关文章

字符串匹配KMP算法中Next[]数组和Nextval[]数组求法

数据结构课本上给了这么一段算法求nextval9[]数组 1 int get_nextval(SString T,int &nextval[ ]) 2 { 3 //求模式串T的next函数修正值并存入数组nextval. 4 i=1; nextval[1]=0; j=0; 5 while(i<T[0] 6 { 7 if(j==0||T[i]==T[j]) 8 { 9 ++i; 10 ++j; 11 if (T[i]!=T[j]) 12 nextval[i]=j; 13 else 14 nex

KMP算法的next[]数组通俗解释

我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度. 当然我们可以看到这个算法针对的是子串有对称属性,如果有对称属性,那么就需要向前查找是否有可以再次匹配的内容. 在KMP算法中有个数组,叫做前缀数组,也有的叫next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大.

KMP算法-之next数组-详解

我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度. 当然我们可以看到这个算法针对的是子串有对称属性,如果有对称属性,那么就需要向前查找是否有可以再次匹配的内容. 在KMP算法中有个数组,叫做前缀数组,也有的叫next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大.

[算法]找出数组当中的中枢元素

给定一个整型数组,找出pivot,使得对于任意i < pivot,a[i] <=a[pivot],对于i > pivot,a[i]>=a[pivot],只能用一个额外的数组,和少量空间. 思路 1.使用一个数组t记录,t[i]记录的是a[0]~a[i]的最大值 int *t = new int[n]; for(int i = 0, max = ~0; i < n; ++i){ if(a[i] > max){ max = a[i]; } t[i] = max; } 2.从

(算法)求数组中出现频率最高的数

不准备实现算法先,根据21题和前辈的经验,这道题的真正考核点不在于解决这个问题,而在于拿到这个问题以后题的问题. 正常的一个做法,一次扫描然后用HASHMAP进行一个统计,然后再扫描一次HASHMAP获得频率最高的数.时间是O(N)空间也是O(N). 还有一种是做排序,然后扫描一次根据下标计算可以得到频率最高的数(可以避免空间消耗?). (不知道是否还有别的做法?) 据说我们应该先问这个数组是否已经排序?(想得美) 然后是否已经知道这个数的大概出现频率(比如说超过一半) 是否可以用额外空间?是否

hdu3336解读KMP算法的next数组

查看原题 题意大致是:给你一个字符串算这里面所有前缀出现的次数和.比如字符串abab,a出现2次,ab出现2次,aba出现1次,abab出现1次.总计6次. 并且结果太大,要求对1007进行模运算. AC代码 #include <iostream> using namespace std; #include <string> string s; int n,Next[200005]; void getNext() { int len = n; Next[0]=-1; int i=0

算法学习笔记 KMP算法之 next 数组详解

最近回顾了下字符串匹配 KMP 算法,相对于朴素匹配算法,KMP算法核心改进就在于:待匹配串指针 i 不发生回溯,模式串指针 j 跳转到 next[j],即变为了 j = next[j]. 由此时间复杂度由朴素匹配的 O(m*n) 降到了 O(m+n), 其中模式串长度 m, 待匹配文本串长 n. 其中,比较难理解的地方就是 next 数组的求法.next 数组的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀,也可看作有限状态自动机的状态,而且从自动机的角度反而更容易推导一些. "前

【bzoj3289】Mato的文件管理 离散化+莫队算法+树状数组

原文地址:http://www.cnblogs.com/GXZlegend/p/6805224.html 题目描述 Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.Mato有一个习惯,他总是从文件大小从小到大看资料.他先把要看的文件按编号顺序依次拷贝出来,再用他写的排序程序给文件大小排序.排

数字切割成数组

工作需要  写了个让10-999的数字切割成数组的 function spnum(num){ num=parseInt(num); if(num<10||num>999)return; var nums=num<100?cut(2,num):cut(3,num); function cut(count,num){ var arr=[],num=num.toString(); for(var i=0;i<count;i++){ arr[i]=num.substr(i,1); } re