经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Oracle » 查看文章
海盗分金问题SQL求解(贪心算法)
来源:cnblogs  作者:九命猫幺  时间:2019/9/20 13:22:45  对本文有异议

问题

经济学上有个“海盗分金”模型:是说5个海盗抢得100枚金币,他们按抽签的顺序依次提方案:首先由1号提出分配方案,然后5人表决,超过半数同意方案才被通过,否则他将被扔入大海喂鲨鱼,依此类推,假设海盗是足够聪明的先利己再伤人,最后方案是怎样的?

网上百度来的的代码

  1. with a as
  2. (select 101 - rownum n from dual connect by rownum <102),
  3. max_one as
  4. (select max(n) max1 from a),
  5. max_two as
  6. (select /*+leading(p2,p1) use_nl(p1) */ p2.n max2,p1.n max1
  7. from a p1,a p2
  8. where p1.n+p2.n=100
  9. and p1.n=(select max1 from max_one)
  10. and rownum=1),
  11. max_three as
  12. (select /*+leading(p3,p2,p1) use_nl(p2) use_nl(p1)*/ p3.n max3,p2.n max2,p1.n max1
  13. from a p1,a p2,a p3,max_two
  14. where p1.n+p2.n+p3.n=100
  15. and sign(p2.n-max2)+sign(p1.n-max1)>=0
  16. and rownum=1),
  17. max_four as
  18. (select /*+leading(p4,p3,p2,p1) use_nl(p3) use_nl(p2) use_nl(p1)*/ p4.n max4,p3.n max3,p2.n max2,p1.n max1
  19. from a p1,a p2,a p3,a p4,max_three
  20. where p1.n+p2.n+p3.n+p4.n=100
  21. and sign(p3.n-max3)+sign(p2.n-max2)+sign(p1.n-max1)>0
  22. and rownum=1),
  23. five as
  24. (select /*+leading(p5,p4,p3,p2,p1) use_nl(p4) use_nl(p3) use_nl(p2) use_nl(p1)*/ p5.n n5, p4.n n4,p3.n n3,p2.n n2,p1.n n1
  25. from a p1,a p2,a p3,a p4,a p5,max_four
  26. where p1.n+p2.n+p3.n+p4.n+p5.n=100
  27. and sign(p4.n-max4)+sign(p3.n-max3)+sign(p2.n-max2)+sign(p1.n-max1)>=0
  28. and rownum=1)
  29. select * from five;

严格筛选数据优化后

  1. with a as
  2. (select 101 - rownum n from dual connect by rownum <102),
  3. max_one as
  4. (select max(n) max1 from a),
  5. max_two as
  6. (select /*+leading(max_one,p2,p1) use_nl(p2) use_nl(p1) */ p2.n max2,p1.n max1
  7. from a p1,a p2,max_one
  8. where p1.n+p2.n=100
  9. and p1.n>=max1
  10. and rownum=1),
  11. max_three as
  12. (select /*+leading(max_two,p3,p2,p1) use_nl(max_two) use_nl(p2) use_nl(p1)*/ p3.n max3,p2.n max2,p1.n max1
  13. from a p1,a p2,a p3,max_two
  14. where p1.n+p2.n+p3.n=100
  15. AND p3.n+p2.n<=100
  16. and CASE WHEN p2.n > max2 THEN 1 ELSE -1 END +
  17. CASE WHEN p1.n > max1 THEN 1 ELSE -1 END >= 0
  18. and rownum=1),
  19. max_four as
  20. (select /*+leading(max_three,p4,p3,p2,p1) use_nl(max_three) use_nl(p3) use_nl(p2) use_nl(p1)*/ p4.n max4,p3.n max3,p2.n max2,p1.n max1
  21. from a p1,a p2,a p3,a p4,max_three
  22. where p1.n+p2.n+p3.n+p4.n=100
  23. AND p4.n+p3.n <= 100
  24. AND p4.n+p3.n+p2.n <= 100
  25. and CASE WHEN p3.n > max3 THEN 1 ELSE -1 END +
  26. CASE WHEN p2.n > max2 THEN 1 ELSE -1 END +
  27. CASE WHEN p1.n > max1 THEN 1 ELSE -1 END >= 0
  28. and rownum=1),
  29. five as
  30. (select /*+leading(max_four,p5,p4,p3,p2,p1) use_nl(p5) use_nl(p4) use_nl(p3) use_nl(p2) use_nl(p1)*/ p5.n n5, p4.n n4,p3.n n3,p2.n n2,p1.n n1
  31. from a p1,a p2,a p3,a p4,a p5,max_four
  32. where p1.n+p2.n+p3.n+p4.n+p5.n=100
  33. AND p5.n+p4.n <= 100
  34. AND p5.n+p4.n+p3.n <= 100
  35. AND p5.n+p4.n+p3.n+p2.n <= 100
  36. AND CASE WHEN p4.n > max4 THEN 1 ELSE -1 END +
  37. CASE WHEN p3.n > max3 THEN 1 ELSE -1 END +
  38. CASE WHEN p2.n > max2 THEN 1 ELSE -1 END +
  39. CASE WHEN p1.n > max1 THEN 1 ELSE -1 END >= 0
  40. and rownum=1)
  41. select * from five;

结果

image

原文链接:http://www.cnblogs.com/yongestcat/p/11555829.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号