大家来讨论一个算法

alfwolf 2014-08-13 08:36:09
加精
场景:
你有一支枪,枪上有三个按键:发射、能量X2、能量/2(需要之前的发射能量是偶数)。
你面前有一队敌人,消灭每个敌人所需能量不尽相同,你可以且仅能一次设置好发射的初始能量,然后通过加倍和减半按钮来调节当前发射能量,每次发射前的发射能量均为初始设置能量。

要求:
你需要根据当前所有敌人的具体情况设置好初始能量,最少浪费能量的情况下消灭所有敌人。

敌人个数N: 1<= N <= 10000
消灭单个敌人所需能量Xi: 1 <= Xi <= 10000

示例1:
2
7 31
结果:2

示例2:
3
4 8 2
结果:0

示例说明:
示例1:第一行表示敌人个数N,第二行表示消灭每个敌人所需的能量分别为Xa=7和Xb=31,我们将枪的初始能量设置为8,消灭第一个敌人浪费1点能量,然后按X2按钮两次,发射能量变为32,消灭第二个敌人浪费1点能量。最终总共浪费2点能量,结果为2。

示例2:各行数据意义同示例1,初始能量设置为4,消灭第一个敌人浪费能量0,按X2按钮能量变为8,消灭第二个敌人浪费能量0,按/2按钮发射能量变为2,消灭第三个敌人浪费能量0。最终总共浪费0点能量,结果为0。

请给出如何设置初始能量以最少浪费能量的算法。
...全文
4292 151 打赏 收藏 转发到动态 举报
写回复
用AI写文章
151 条回复
切换为时间正序
请发表友善的回复…
发表回复
大树学长 2014-08-29
  • 打赏
  • 举报
回复
我想到 了一个不知道前面有没有讲过 我没看 是这样:求最小误差。 首先对要消灭敌人的能量,做一个排序得到最大值和最小值。 关键点:能量设置初始值为:2x,还有一个x和4x; 将2x=最小值(如果为质数,2x+1) for循环到2x=最大值。 for(2x = 最小值;2x《=最大值;2x=2x+2) { 判断【消灭敌人的能量】最接近x、2x、4x中的那个值 并且【消灭敌人的能量】要小于这个值 sum【x】 += 消灭每个敌人的剩余能量; 在for循环中将所有能量遍历一遍,并将每次的剩余能量相加 } 每次2x等于一个值时都求一下那个浪费的能量值:sum【数组】 判断:sum【数组】数值小于0的直接排除 取为正数并且最接近0的值。就是最小剩余能量。 这个时候的2x就是最优化的初始能量值。 其实问题就是在剩余能量最小的情况下得到初始能量值。
wust小吴 2014-08-27
  • 打赏
  • 举报
回复
引用 152 楼 lionghua 的回复:
楼主,按照我的这个算法没问题的。 EG: 7,31---->(7+31)/2 = 19----->x = 2^5 = 32,所以初始能量32,31(浪费1),7(两次减半,浪费1)。 4,8,2---->(4+8+2)/3 约得 5----->x=2^3 = 8,所以初始能量为8,(不浪费) 1,2,3,4,5,6----->(1+2+3+4+5+6)/6约得4----->x=2^2 = 4,所以初始能量为4,(0,0,1,0,3,2)浪费6. 。。。。。。。。。。。。。
乱说 1,2,3,4,5,6 设置为,1,浪费分别为:(0,0,1,0,0,1,2)浪费为4 1,2,3,4,5,6,设置为2,浪费分别为:(0,0,1,0,1,2)浪费为4,
wust小吴 2014-08-27
  • 打赏
  • 举报
回复
引用 158 楼 lionghua 的回复:
[quote=引用 157 楼 u014737138 的回复:] [quote=引用 152 楼 lionghua 的回复:] 楼主,按照我的这个算法没问题的。 EG: 7,31---->(7+31)/2 = 19----->x = 2^5 = 32,所以初始能量32,31(浪费1),7(两次减半,浪费1)。 4,8,2---->(4+8+2)/3 约得 5----->x=2^3 = 8,所以初始能量为8,(不浪费) 1,2,3,4,5,6----->(1+2+3+4+5+6)/6约得4----->x=2^2 = 4,所以初始能量为4,(0,0,1,0,3,2)浪费6. 。。。。。。。。。。。。。
乱说 1,2,3,4,5,6 设置为,1,浪费分别为:(0,0,1,0,0,1,2)浪费为4 1,2,3,4,5,6,设置为2,浪费分别为:(0,0,1,0,1,2)浪费为4,[/quote] 先求均值,懂吗?不是乱设置的[/quote] 哎 你咋没有明白我的意思呢?你设置为4就不是浪费能量最少的解,明白吗,你设置4浪费了多少,4难道大于6??? 所以你这算法不行
lionghua 2014-08-27
  • 打赏
  • 举报
回复
引用 157 楼 u014737138 的回复:
[quote=引用 152 楼 lionghua 的回复:] 楼主,按照我的这个算法没问题的。 EG: 7,31---->(7+31)/2 = 19----->x = 2^5 = 32,所以初始能量32,31(浪费1),7(两次减半,浪费1)。 4,8,2---->(4+8+2)/3 约得 5----->x=2^3 = 8,所以初始能量为8,(不浪费) 1,2,3,4,5,6----->(1+2+3+4+5+6)/6约得4----->x=2^2 = 4,所以初始能量为4,(0,0,1,0,3,2)浪费6. 。。。。。。。。。。。。。
乱说 1,2,3,4,5,6 设置为,1,浪费分别为:(0,0,1,0,0,1,2)浪费为4 1,2,3,4,5,6,设置为2,浪费分别为:(0,0,1,0,1,2)浪费为4,[/quote] 先求均值,懂吗?不是乱设置的
sinat_19945607 2014-08-22
  • 打赏
  • 举报
回复
领教了高手真的太多了,下个导航我容易吗
wust小吴 2014-08-21
  • 打赏
  • 举报
回复
引用 154 楼 alfwolf 的回复:
各位,其实已经有答案了,过两天发上来。
给分的时候请多给我点啊,我急需分数发表问题,谢谢支持!!!
alfwolf 2014-08-21
  • 打赏
  • 举报
回复
各位,其实已经有答案了,过两天发上来。
anthow 2014-08-20
  • 打赏
  • 举报
回复
引用 24 楼 maenyou 的回复:
[quote=引用 21 楼 rcfalcon 的回复:] [quote=引用 20 楼 alfwolf 的回复:] [quote=引用 19 楼 rcfalcon 的回复:] [quote=引用 18 楼 alfwolf 的回复:] [quote=引用 15 楼 rcfalcon 的回复:] 感觉算法挺简单的,数值范围因为不大(小于10000),我们把题目做一下简单的数学变化: 因为不允许非整数的存在,实际问题就转变为需要找一个质数(素数)X,使得 X*(2^n)形成一个数的序列,再用题目输入给定的敌人的血量去求差,使得差的和最小。 由于数据量不大,我们可以先将10000以内的素数全部计算形成表,然后挨个用这个表去对应题目的输入,对于输入的每个数,去表里找比这个数大的数相减,取最小值。计算复杂读O(n) 可能上面没描述得特别清楚,我根据题目给定的例子举例一下: 对于素数2,形成表: 1、2、4、8、16…… 对于素数3:,形成表:3、6、12、…… 对于素数5,形成表:5、10、20、…… 对于素数7,形成表:7、14、28、…… 对于示例1,(7、31),我们遍历以上表,每个数取表里比他大的那个数去相减,得出 素数2的表 sum= (8-7) + (32-31) = 2 素数3的表 sum=(12-7) + (48-31) = 22 …… 所以最小值为2
先赞一个!!! 其实我们应该需要奇数表,而非素数表。 举例:如果两个敌人的血量都是15... [/quote] 是的,素数不全,是奇数的表。[/quote] 兄弟,很喜欢你的钻研风格,希望以后可以多向你请教和探讨。 [/quote] 客气,年轻的时候搞过一点信息学OI,现在老了,脑子也转不动了。[/quote]奇数也不行吧,如果全是6的话[/quote] 那就直接设置初始量为3啊
qq_19823019 2014-08-20
  • 打赏
  • 举报
回复
我是来赚分的 ,。
lionghua 2014-08-20
  • 打赏
  • 举报
回复
楼主,按照我的这个算法没问题的。 EG: 7,31---->(7+31)/2 = 19----->x = 2^5 = 32,所以初始能量32,31(浪费1),7(两次减半,浪费1)。 4,8,2---->(4+8+2)/3 约得 5----->x=2^3 = 8,所以初始能量为8,(不浪费) 1,2,3,4,5,6----->(1+2+3+4+5+6)/6约得4----->x=2^2 = 4,所以初始能量为4,(0,0,1,0,3,2)浪费6. 。。。。。。。。。。。。。
lionghua 2014-08-20
  • 打赏
  • 举报
回复
1,先求敌人需要的平均能量Xneed, 2,再算2^x>Xneed,求出x.
九天沐风 2014-08-20
  • 打赏
  • 举报
回复
是做游戏开发的
alfwolf 2014-08-19
  • 打赏
  • 举报
回复
大家再多想想
会思考的草 2014-08-19
  • 打赏
  • 举报
回复
初始设定能量必须是偶数?
gmxydm 2014-08-19
  • 打赏
  • 举报
回复
这个问题的终极解决办法是生成一个100万X20的一个表单,没有比这个更快的办法了,也就是生成一个80M的表单,然后查表单,这样绝对可以满足1秒钟搞出最优的解法!!!!!
伊顺鸣 2014-08-19
  • 打赏
  • 举报
回复
还真的是很难的啊。。。
wust小吴 2014-08-19
  • 打赏
  • 举报
回复
引用 127 楼 maenyou 的回复:
[quote=引用 122 楼 u014737138 的回复:] [quote=引用 2 楼 alfwolf 的回复:] 呵呵,大家都来看看,参与者都有丰厚奖励 :)
请一直看完,我把所有的想法都说了,后面是动态规划,应该是你要的, 我来说说我的想法啊,这个问题这样看: 理想状态下:(这里要考虑那个奇数出现整除的情况),我们可以开始剔除掉一些特殊的情况 1.对每一个enemy都有相应的消灭能量 无非是两种值 奇数和偶数 如果是奇数:那么浪费能量为 1 如果是偶数:那么浪费能量为 0 也就是说 :最终浪费能量的最少值应该一定是 敌人中需要消灭它所需能量值为奇数的个数之和 2.再来看 问题的求解:设置初始能量值 使得浪费能量最少 如果你的题目没有问题,而且我的理解每错的话:你这个求解附带的条件使得浪费能量最少就很难理解了,完全没有必要! 你的问题中没有这个附带条件: 1.设置的初始值使得角色操作的次数最少,就是shouqiang的三个键使用率最少! 2.设置的初始值有没有要求,有些情况下初始值很多,但是效果是一样的! 没有的话 这样一来思路就是: A. 对enemy数量和相应的消灭能量进行奇偶分析 if(奇数) { 消灭能量值入堆栈(或者其他的数据结构)} if(偶数){ 设置2进入堆栈(而且只进行这一次操作,后面碰到偶数就再也不管了)【或者这里设置一个偶数堆栈】} B. 第一种情况下:全是奇数,没有偶数: 从堆栈中找到奇数最小值, 这里举个例子: 1. 2个enemy, 11,33 那么设置初始值为11,浪费能量为0 2. 2个enemy, 7 ,9 那么设置初始值为2,,9等都是一样的,都需要浪费两个能量,那么我们该怎么选择? 第二种情况下:只要有偶数存在,初始值就可以设置为2,因为你也没有限制我可以乘以多少次,假如碰到奇数的话是一定可以 得到2*k+1=奇数,或者减一,那么浪费能量好像也是1,偶数就是浪费0 C.通过分析似乎就只要对奇数进行处理了: 找最小公倍数!!!! 1.奇数序列中正好存在最小公倍数,那么就是这个值了,为初始能量值 2.如果奇数序列中没有存在最小公倍数,那么2一定是可以的,这里只需要验证下2是不是使得浪费最少(私下自己验证,如果数学上成立,代码就可以这样写) 或者在2的情况下: 问题就集中在:递归查找最小公倍数 A.首先分组,把找到的最小公倍数保留下来,剔除该组的其他数,调用函数找 B.将找到的最小公倍数进行再分组,递归找最小公倍数, C.找到最后剩下的值进行处理,一步一步的选择到最优解了 这种思路就是分治法了,分组找到最小公倍数,当一个数据量非常大的时候这种独立的方式消耗将会很大 那么就应该考虑按照动态规划做,那么就是需要把分组的各种状态联系起来就可以实现转换了: 用两个for循环,内层循环的临界值是外层循环的值 for(i,,,,,) for(j,j<i,,,){ if()} 这样就实现了动态规划,解决了递归带来的冗余问题,算法效率就会提高 首先就是分析: 无数条数据我们怎么去结合他们找到我们需要的解,使得花销(查找和计算)代价最少呢? 只能从最小的子问题去做了,就是先分析两两结合的最小公倍数,从中找出最优的情况, 然后去测试三个数据的情况,:这里呢就必须结合第一步前面的两两结合的值和第三个值结合,从中找出最优解 以此按照这个思路进行,就是动态规划了, 下面就是具体实现了: 阶段划分下: 1.初始状态为1个数,最小公倍数为自己,计算量为0,第一个值就可以, 2.第二阶段,计算两两结合,得到最小公倍数,共有n-1组,找到我们的最优解 3.第三个阶段,把第二阶段的结果与剩下的数进行最小公倍数计算,共有n-2组,找到我们的最优解 。。。。。 最后一个阶段,是n个计算最小公倍数,只有1组了,也就是问题的最优解了 阶段决策: 这里呢就是计算最少浪费能量值的计算方法SUM(参数),根据这个决策找到每一个阶段的最优解了, SUM()=min{值1,值2,值3,。。。。。} 这里的计算方式我们采用上面的大家提供的方法K=POW(X,K)-A[I],其中x就是每一阶段中找到的最小公倍数,把所有的K相加就能得出最少浪费值,然后进行比较,那个最小哪个就是最优解了。这里可以采用堆栈,存储每次的最少能量值 至此分析结束, 再把那些偶数和奇数的情况全部 整 合到一起就可以了,就是用同一的循环处理,不用分奇数和偶数了,完全可以采用。 [/quote]少年,你没有了理解题目[/quote]
引用 127 楼 maenyou 的回复:
[quote=引用 122 楼 u014737138 的回复:] [quote=引用 2 楼 alfwolf 的回复:] 呵呵,大家都来看看,参与者都有丰厚奖励 :)
请一直看完,我把所有的想法都说了,后面是动态规划,应该是你要的, 我来说说我的想法啊,这个问题这样看: 理想状态下:(这里要考虑那个奇数出现整除的情况),我们可以开始剔除掉一些特殊的情况 1.对每一个enemy都有相应的消灭能量 无非是两种值 奇数和偶数 如果是奇数:那么浪费能量为 1 如果是偶数:那么浪费能量为 0 也就是说 :最终浪费能量的最少值应该一定是 敌人中需要消灭它所需能量值为奇数的个数之和 2.再来看 问题的求解:设置初始能量值 使得浪费能量最少 如果你的题目没有问题,而且我的理解每错的话:你这个求解附带的条件使得浪费能量最少就很难理解了,完全没有必要! 你的问题中没有这个附带条件: 1.设置的初始值使得角色操作的次数最少,就是shouqiang的三个键使用率最少! 2.设置的初始值有没有要求,有些情况下初始值很多,但是效果是一样的! 没有的话 这样一来思路就是: A. 对enemy数量和相应的消灭能量进行奇偶分析 if(奇数) { 消灭能量值入堆栈(或者其他的数据结构)} if(偶数){ 设置2进入堆栈(而且只进行这一次操作,后面碰到偶数就再也不管了)【或者这里设置一个偶数堆栈】} B. 第一种情况下:全是奇数,没有偶数: 从堆栈中找到奇数最小值, 这里举个例子: 1. 2个enemy, 11,33 那么设置初始值为11,浪费能量为0 2. 2个enemy, 7 ,9 那么设置初始值为2,,9等都是一样的,都需要浪费两个能量,那么我们该怎么选择? 第二种情况下:只要有偶数存在,初始值就可以设置为2,因为你也没有限制我可以乘以多少次,假如碰到奇数的话是一定可以 得到2*k+1=奇数,或者减一,那么浪费能量好像也是1,偶数就是浪费0 C.通过分析似乎就只要对奇数进行处理了: 找最小公倍数!!!! 1.奇数序列中正好存在最小公倍数,那么就是这个值了,为初始能量值 2.如果奇数序列中没有存在最小公倍数,那么2一定是可以的,这里只需要验证下2是不是使得浪费最少(私下自己验证,如果数学上成立,代码就可以这样写) 或者在2的情况下: 问题就集中在:递归查找最小公倍数 A.首先分组,把找到的最小公倍数保留下来,剔除该组的其他数,调用函数找 B.将找到的最小公倍数进行再分组,递归找最小公倍数, C.找到最后剩下的值进行处理,一步一步的选择到最优解了 这种思路就是分治法了,分组找到最小公倍数,当一个数据量非常大的时候这种独立的方式消耗将会很大 那么就应该考虑按照动态规划做,那么就是需要把分组的各种状态联系起来就可以实现转换了: 用两个for循环,内层循环的临界值是外层循环的值 for(i,,,,,) for(j,j<i,,,){ if()} 这样就实现了动态规划,解决了递归带来的冗余问题,算法效率就会提高 首先就是分析: 无数条数据我们怎么去结合他们找到我们需要的解,使得花销(查找和计算)代价最少呢? 只能从最小的子问题去做了,就是先分析两两结合的最小公倍数,从中找出最优的情况, 然后去测试三个数据的情况,:这里呢就必须结合第一步前面的两两结合的值和第三个值结合,从中找出最优解 以此按照这个思路进行,就是动态规划了, 下面就是具体实现了: 阶段划分下: 1.初始状态为1个数,最小公倍数为自己,计算量为0,第一个值就可以, 2.第二阶段,计算两两结合,得到最小公倍数,共有n-1组,找到我们的最优解 3.第三个阶段,把第二阶段的结果与剩下的数进行最小公倍数计算,共有n-2组,找到我们的最优解 。。。。。 最后一个阶段,是n个计算最小公倍数,只有1组了,也就是问题的最优解了 阶段决策: 这里呢就是计算最少浪费能量值的计算方法SUM(参数),根据这个决策找到每一个阶段的最优解了, SUM()=min{值1,值2,值3,。。。。。} 这里的计算方式我们采用上面的大家提供的方法K=POW(X,K)-A[I],其中x就是每一阶段中找到的最小公倍数,把所有的K相加就能得出最少浪费值,然后进行比较,那个最小哪个就是最优解了。这里可以采用堆栈,存储每次的最少能量值 至此分析结束, 再把那些偶数和奇数的情况全部 整 合到一起就可以了,就是用同一的循环处理,不用分奇数和偶数了,完全可以采用。 [/quote]少年,你没有了理解题目[/quote] 额 理解错了吗,我到认为我楼下的那位跟我一样,题目少了条件,题目给出的案例也很特殊,你自己多举几个例子看看,并且求出他们可能的解,
zhenzhenyo 2014-08-19
  • 打赏
  • 举报
回复
学习学习,楼主真给力
oxfed 2014-08-19
  • 打赏
  • 举报
回复
引用 120 楼 alfwolf 的回复:
[quote=引用 119 楼 oxfed 的回复:] 应该还有条件限制吧,否则 初始值设为1,每次不断按加倍直到 >=杀死目标所需能量,这总是最优的。
呵呵,你确定?[/quote] 想错了。
姜千睿 2014-08-18
  • 打赏
  • 举报
回复
请问。如果我设置了初始能量为5的话,我能按除2的按钮吗
加载更多回复(131)
  在有关算法的书中,有一些叙述非常严谨,但不够全面;另一些涉及了大量的题材,但又缺乏严谨性。本书将严谨性和全面性融为一体,深入讨论各类算法,并着力使这些算法的设计和分析能为各个层次的读者接受。全书各章自成体系,可以作为独立的学习单元;算法以英语和伪代码的形式描述,具备初步程序设计经验的人就能看懂;说明和解释力求浅显易懂,不失深度和数学严谨性。 《算法导论(原书第3版)》选材经典、内容丰富、结构合理、逻辑清晰,对本科生的数据结构课程和研究生的算法课程都是非常实用的教材,在it专业人员的职业生涯中,本书也是一本案头必备的参考书或工程实践手册。    第3版的主要变化:    新增了van emde boas树和多线程算法,并且将矩阵基础移至附录。    修订了递归式(现在称为“分治策略”)那一章的内容,更广泛地覆盖分治法。    移除两章很少讲授的内容:二项堆和排序网络。    修订了动态规划和贪心算法相关内容。    流网络相关材料现在基于边上的全部流。    由于关于矩阵基础和strassen算法的材料移到了其他章,矩阵运算这一章的内容所占篇幅更小。    修改了对knuth-morris-pratt字符串匹配算法讨论。    新增100道练习和28道思考题,还更新并补充了参考文献。

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧