计算24点问题的详细解析(含源码)

24点游戏 数字游戏题解 by starfish [说明:此文改编自我写的一篇解题报告,原题是某年国家集训队组队赛题目] 问题描述 80年代全世界流行一种数字游戏,在中国我们把这种游戏称为“24点”。现在我们 把这个有趣的游戏推广一下:您作为游戏者将得到6个不同的自然数作为操作数, 以及另外一个自然数作为理想目标数,而您的任务是对这6个操作数进行适当的算 术运算,要求运算结果小于或等于理想目标数,并且我们希望所得结果是最优的, 即结果要最接近理想目标数。 您可以使用的运算只有:+,-,*,/,您还可以使用()来改变运算顺序。注意: 所有的中间结果必须是整数,所以一些除法运算是不允许的(例如,(2*2)/4是 合法的,2*(2/4)是不合法的) 下面我们给出一个游戏的具体例子: 若给出的6个操作数是:1,2,3,4,7和25,理想目标数是573; 则最优结果是573:(((4*25-1)*2)-7)*3。 输入: 输入文件名为game.in。输入文件仅一行,包含7个整数,前6个整数Mi, 1<=Mi<=100,表示操作数,最后一个整数T, 1<=T<=1000,表示理想目标数。 输出: 输出文件名为game.out。输出文件有两行,第一行仅一个整数,表示您的程序计算 得到的最优结果;第二行是一个表达式,即您得到的最优结果的运算方案。 输入输出示例: 输入文件 1 2 3 4 7 25 573 输出文件 573 ((4*25-1)*2)-7)*3 算法分析 首先我们要对这个问题进行数学抽象。 定义1:对于有理数组成的多重集合S , f(S) 定义如下: 如果 S 是空集或只包含一个元素,则 f(S)=S ;否则 f(S)=∪ f( ( S-{r1, r2}) ∪ {r} ) ,对于每一个 r=r1+r2 , r1-r2 , r1×r2 ,r1÷r2(r2≠0),且r1, r2取遍 S 中所有元素的组成的二元组。 定义1说明:要计算集合S中的元素通过四则混合运算所能得到的所有值,我们只需 要任取 S 中的两个元素 r1 , r2 ,分别计算 r1 , r2 的加减乘除运算,然后用 所得的结果与 S 中剩下的其他数字进行四则混合运算。只要取遍所有的 r1 , r2 ,最后得到的所有结果的并集就是 S 中的元素通过四则混合运算所能得到的所 有值的集合。 根据上述定义,在本问题中,集合 S 就是由输入中给定的6个正整数组成的集合, 题目所求就是找出 f(S) 中小于或等于目标数的最大数。 定义2:给定两个多重集合 S1 , S2,定义 comb( S1, S2 ) = ∪ { r1+r2 , r1-r2, r1×r2, r1÷r2(r2≠0) } (1.1) 其中 ( r1 , r2 ) ∈ S1 × S2。 定义2实际上定义了两个集合中的元素两两进行加减乘除运算所能得到的结果集合 。 定理1:对于有理数组成的多重集合 S ,如果 S 至少有两个元素,则 f(S)=∪ comb( f(S1), f(S - S1) ) (1.2) 其中 S1 取遍 S 的所有非空真子集。 定理1的含义是:要计算 S 中的元素通过四则混合运算所能得到的所有值,可以先 将 S 分解为两个子集 S1 和 S- S1 ,分别计算 S1 和 S-S1 中的元素进行四则混 合运算所能得到的结果集合,即 f(S1) 和 f(S-S1) ,然后对这两个集合中的元素 进行加减乘除运算,即 comb( f(S1), f(S-S1) ) ,最后得到的所有集合的并集就 是 f(S) 。限于篇幅,定理1的正确性易用数学归纳法证明。 定义1和定理1实际上分别给出了计算f(S)的两种不同的方法。根据定义1,可以递 归地计算f(S) ,其算法伪代码如下: 算法1 function f(S) begin 1. if |S| < 2 2. then return S 3. else begin 4. T ← Φ 5. for each (r1, r2) in S do 6. begin 7. r ← r1 + r2; 8. T ← T + f(S – {r1, r2} + {r}); 9. r ← r1 - r2; 10. T ← T + f(S – {r1, r2} + {r}); 11. r ← r1 * r2; 12. T ← T + f(S – {r1, r2} + {r}); 13. if (r2 <> 0) and (r1 mod r2 = 0) then 14. begin 15. r ← r1 / r2; 16. T ← T + f(S – {r1, r2} + {r}); 17. end 18. end 19. return T; 20. end end 上述伪代码中使
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值