记一道毫无思路的算法题

今天贤内给了我一道很实际的算法题,把我彻底难住了,实在想不出来,于是写此博文以记之。

背景是这样的,现在有一个付款明细的Excel,里面有为哪个发票,哪个公司应付多少钱的明细,明细数据是62条,现在知道我们已经付出的金额为Sum,请问到底哪些发票是已付款的。

这是62条明细数据:

653165.00
356029.11
220896.45
146362.00
1847670.00
3018518.91
1347553.07
145010.74
339784.84
199350.28
1206114.00
882000.00
253246.13
720000.00
24194.07
1518952.00
139453.48
200415.00
812044.00
9032764.57
3960608.05
1855126.31
7409087.18
608094.66
225519.59
627912.23
109897.52
1215819.87
4220245.50
94299.00
96547.00
92616.01
597100.54
880440.00
343991.59
70468.19
1092418.47
66911.94
80138.65
1398551.14
172287.48
691097.86
2371693.44
3773148.63
83898.33
89922.75
2619220.46
1179477.63
3440250.98
700000.00
997545.00
272523.00
3009976.00
451891.44
2111314.00
306377.00
142329.00
2057178.00
9340.00
249027.00
60811.50
51188.50

付款的金额为:

35857936.42

这听起来是一个很简单的算法题,其实就是算组合嘛,把每种组合的金额进行相加,如果等于Sum金额,那么就输出这种组合。于是网上找找组合函数的代码,很快就写出了这个程序。而且使用了一些简单的测试程序,确认计算是正确的。但是真正用到这个事情中,却崩溃了,计算量太大,根本算不出来。

仔细一想,对于每个数字,要么出现,要么不出现,那么其计算复杂度就是O(2^n),这里n=62,那么差不多就得计算2的62次,遍历每一种组合,才能找到全部答案。天啊!2的62次方!

根本不可能完成啊。想了又想,怎么都没有想到好的办法把复杂度降下来,伤心。不知道有没有大神能够解决这个问题。

这还只是一次数据,以后说不定还有100条明细,200条明细的,就这破算法,那更是天文数字,怎么可能算得出来啊?!

附上现有的代码下载

更新:

好吧,看来我太无知了,这个问题是没有解决办法的,StackOverflow的讨论:http://stackoverflow.com/questions/4355955/subset-sum-algorithm

而且还有专门的维基百科页面:http://en.wikipedia.org/wiki/Subset_sum_problem#Pseudo-polynomial_time_dynamic_programming_solution

时间: 2024-11-03 22:51:44

记一道毫无思路的算法题的相关文章

一道简单的字符串算法题,有空的大虾进来帮忙看看呀~~~

问题描述 /** * 该方法将传入的字符串 从右往左按照指定的insertNumber值位 插入一个指定的insertChar代表的符号. * * @param str * 需要进行转换的字符串 * @param insertChar * 需要插入的字符 * @param insertNumber * 字符插入的位置 * @return 返回一个插入后的新字符串 举例,如果传入的字符串值为"123909000", * insertChar为">>",in

一道算法题,看看大家的思路(续)

"一道算法题,看看大家的思路",看了众多的回复,本人愚钝,没有看明白其中的奥妙.在细细研究<编程之美>中的文章后,终于理解了这个算法的思路.现将这个算法的演算过程以及代码实现(VB2005)赋予其后,和各位交流. 现再将题目复述一遍: 题目描述:有31,-41,59,26,-53,58,97,-93,-23,84十个数.SUM(N,M)表示从第N个数到到第M个数的和.例如:SUM(2,3)=-41+59=18.问:最大的和是多少?对应的N和M是多少? 先不管N和M的计算,直

求助一道二维数组交换特定元素位置的算法题,谢谢大家!

问题描述 求助一道二维数组交换特定元素位置的算法题,谢谢大家! 刚试验了一下出了新问题- - 比如,一开始是左边的数组,我想"把2个0去掉,然后0上面的2就掉下来了",形成右边的新数组 然后我用了循环遍历,比如只看第二列,我的做法是"从下往上找,遇到0,就和0上面的数字交换",结果成了下面这个样子了- - 我有个改进想法是"还是从下往上找,遇到0之后判断上面的是不是0,如果是0,再继续向上再找,直到不是0,然后把这个数赋值给一开始那个0的位置",

算法题——一道数字组合的题目的求解

题目:给定一个数字,和一个范围,产生所有在范围内的不重复的数字之和,和等于给定的数字. 举例:给数字12,范围3-6.可以产生以下5个组合: 1.3+3+3+3 2.3+3+6 3.3+4+5 4.4+4+4 5.6+6 要求给出最快实现,并且是非递归. 这是某人给我出的一道算法题.经过考虑,给出了解法.最快的谈不上(算法无止境.人外有人),没有用递归.   还是以题目的例子说明,数字12,范围3-6.给出了5种组合.将这5种组合改写一下 3+3+3+3=3*4+4*0+5*0+6*0 记作:(

求助一道算法题,关于数组算法

问题描述 求助一道算法题,关于数组算法 有一个字符串数组{"用户1,商品1,200","用户2,商品2,100","用户3,商品1,300","用户4,商品3,50","用户5,商品3,50"},写的方法需要返回的是{"用户2,商品2","用户3,商品1","用户4,商品3"}也就是说比较下每种商品的最高价格是谁,并返回谁买了,如果价格相同取最先买

基础算法题,求思路和代码

问题描述 基础算法题,求思路和代码 问题 E: L1-6. 连续因子 时间限制: 1 Sec 内存限制: 128 MB 题目描述 一个正整数N的因子中可能存在若干连续的数字.例如630可以分解为3*5*6*7,其中5.6.7就是3个连续的数字.给定任一正整数N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列. 输入 输入在一行中给出一个正整数N(1<N<231). 输出 首先在第1行输出最长连续因子的个数:然后在第2行中按"因子1*因子2*--*因子k"的格式

时间复杂度-求解一道acm算法题,在线等!!

问题描述 求解一道acm算法题,在线等!! 有N个D维向量,求解每个向量到其他向量的最短距离. 只要求解每个向量到其他向量的最短距离就可以了. 距离采用欧式距离表示. 时间复杂度近似于O(DN) 解决方案 http://zhidao.baidu.com/link?url=Xt0N7upNLbk_Ik4uBxPx6Nl2n3JVp_ry9Of6YAnvQiVIkwuCXuiIPSoanHbeaf07M8zjTy-qpD4A4iFe1dXDuq

设计-一道二重积分算法题,要求复杂度低于n^2

问题描述 一道二重积分算法题,要求复杂度低于n^2 对于x∈X{x0,x1,x2,...,xn-1},y∈Y{y0,y1,y2,...,yn-1},又已知一个矩阵C,C中的元素C(i,j)的值为p(xi,xj) 设计一个算法计算 假设这里log(.)属于基本算符,有没有让它的复杂度低于n^2的方法? 解决方案 每天一道算法题2 删除链表结点(时间复杂度为O(1)))

从一道算法题说去2

今天的算法题是关于 字符串的最小编辑距离问题求解. 1. 什么是字符串编辑距离 编辑距离(Edit Distance),又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可的编辑操作包括将一个字符替换成另一个字符,添加一个字符,删除一个字符. 例如将kitten一字转成sitting: a. sitten (k→s)  b. sittin (e→i)  c. sitting (→g)  俄罗斯科学家Vladimir Levenshtein在1965年提出