用水晶来搭建一座双塔
问题描述:2001年9月11日,一场突发的灾难将纽约世界贸易中心大厦夷为平地,Mr. F曾亲眼目睹了这次灾难。为了纪念“9?11”事件,Mr. F决定自己用水晶来搭建一座双塔。
Mr. F有N块水晶,每块水晶有一个高度,他想用这N块水晶搭建两座有同样高度的塔,使他们成为一座双塔,Mr. F可以从这N块水晶中任取M(1≤M≤N)块来搭建。但是他不知道能否使两座塔有同样的高度,也不知道如果能搭建成一座双塔,这座双塔的最大高度是多少。所以他来请你帮忙。
给定水晶的数量N(1≤N≤100)和每块水晶的高度Hi(N块水晶高度的总和不超过2000),你的任务是判断Mr. F能否用这些水晶搭建成一座双塔(两座塔有同样的高度),如果能,则输出所能搭建的双塔的最大高度,否则输出“Impossible”。 和本站的 高德纳书中一道很普通的题目类似,只是问题规模更大,且没有有效的优化手段。 这个算法效率如何?
开一个二维数组f[ i ][ j ]来保存加入第i个数后,在这堆已加入的数里取出其中两组,差为j的这两组数的最大和为 f [ j ]。 看来$2#$下的结论有点武断,骗了不少人(包括Fans:'(),以为真的没有好方法。
其实就是状态数为$1001$*$1001$的动态规划问题。
其中第一个$1001$表示第一座塔的高度有$0$、$1$、$2$、$...$、$1000$共$1001$种可能。
第二个$1001$表示第二座塔的高度也有$0$、$1$、$2$、$...$、$1000$共$1001$种可能。
初始时状态$$有效,其余状态无效。
如果状态$$有效,那么考虑下一座高度为$h$的塔,可以到达状态$$和$$。
于是把状态$$和$$设置为有效,并且原始状态$$仍然有效。
把$N$座塔全考虑完后,依次检查状态$$、$$、$$、……、$$是否有效,即可找到双塔的最大高度。
最坏情况的运算次数:$1001$*$1001$*$100$=$10^8$
是可以在$1$秒之内出结果的。
如果规模再大一点,就不能保证在$1$秒之内出结果。
$3#$的方法更巧妙。
可以解决更大规模的问题。
比如$1000$块水晶,高度总和不超过$100000$。
页:
[1]