云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > Zplhz - 智破连环阵

Zplhz - 智破连环阵

  • 62 次阅读
  • 3 次下载
  • 2025/5/7 3:05:34

NOI 2003 全国信息学奥林匹克竞赛试题 解题报告——Day2——Problem3——智破连环阵(Zplhz)

南京市外国语学校 朱泽园

深度优先搜索 搜索确实是一种无奈之下的选择,深度优先搜索就是把所有的情况都考虑进去,找出最优的。可以进行的优化有两种:

1、分枝定界、A*搜索。在正式搜索之前,进行一次预先的贪心处理,尽可能地缩小搜索范围。每次将当前状态,以及接下来达到目标所最少需要的炸弹数(估值)相加,如果大于等于当前的最少炸弹数,那么就剪枝。

2、即使这样,遇到了大数据还是铁定超时,为了让程序在时限内出界,可以适当卡结点。就是已经处理的情况数量,大于一个固定值的时候,输出当前较优值并且退出。

可惜这种算法,仍然无法得到一个较好的分值。 宽度优先搜索——IDA*搜索 为了尽可能缩小处理的情况总数,我们自然而然会想到宽度优先搜索。因为宽度优先搜索从优到劣地对序列进行扩展,对于所有比最优情况劣的状态,都是不会被扩展出来的。但是这一道题目会出现数量级别高达O(N!)的状态,空间显然是承受不住的。此时我们选用DFS ID搜索。

ID就是Iterative Deepening,说白了也就是不断地将深度进行加深,刚开始搜索深度为1的所有状态,如果没找到解,就搜索深度为2的所有状态……这个算法在一定程度上是BFS搜索的一种DFS形式扩展,空间复杂度被降低了,时间复杂度却不会上升太高。在这种搜索中,我们可以预先用A*的估值函数算出下界再开始深度加深,另外仍然可以使用分值定界A*,以及卡结点的优化方法。但是结果仍然不理想(参见“程序结果”) 冒险优化 5

NOI 2003 全国信息学奥林匹克竞赛试题 解题报告——Day2——Problem3——智破连环阵(Zplhz)

南京市外国语学校 朱泽园

注意到“问题简述”中,我将“测试数据是随机生成的”这句话加了下划线! 搜索时,把所能够扩展的状态,按照所能炸掉目标的数量从大到小排序。如果每一次我们都选择最大的(局部利益最优的),那么这就是一个贪心过程。在随机生成的数据中,分析一个最优的使用炸弹的序列,它在每一步所选取的是局部利益第几优的,不难发现大部分都是选取局部最优的!

这给我们什么启发呢?我们是不是能限定每次只选取局部利益前X优的进行搜索呢?这样程序的复杂度从O(N!)降到了O(X^N)级别,而且大多数情况下可以剪枝,是很有效果的!(如果X选取2,那么测试数据中有一个点得9分,一个点得11分,还有一个点超时)

仔细分析一下可以知道,选取“局部利益最优”的步骤还是非常之多的,如果每一步我们都考虑“次优局部利益”,着实还是一种浪费!另外,X取2也不是很符合实际,如果要拿满分甚至更多的分,势必要把X设定为3!

这时候我想到一个限定选取“次优局部利益”次数的算法。我们限定选取“次优局部利益”的总次数上限为MIDDLE_NODE_COUNT,限定选取“第三优局部利益”的总次数上限为LARGE_NODE_COUNT。因为最多M个目标,所以MIDDLE_NODE_COUNT取8左右比较合适,LARGE_NODE_COUNT取2左右比较合适。 总体比较与感想 这道题目的标准数据是两个搜索程序综合而得的,而且运行了相当长的时间才出结果。在考场上的我们,只有6sec的时间限制,强力冒险剪枝自然是必不可少的。

我在本题中使用的冒险剪枝是非常有效并且典型的。在搜索超时的情况下,

6

NOI 2003 全国信息学奥林匹克竞赛试题 解题报告——Day2——Problem3——智破连环阵(Zplhz)

南京市外国语学校 朱泽园

大多数选手会选择卡时,或者卡结点的方法。然而往往这种情况下,只搜索了搜索树的一小部分:

……

而我这样的贪心式搜索,可以覆盖搜索树的大部分地方,并且都是较优值!

[程序]

数据结构&算法设计 #define SMALL_NODE 1 #define MIDDLE_NODE 2 #define LARGE_NODE 3

#define MIDDLE_NODE_COUNT 8 #define LARGE_NODE_COUNT 2

代表前1~SMALL_NODE优的局部状态一定搜索,前SMALL_NODE+1~ MIDDLE_NODE优的局部状态搜索MIDDLE_NODE_COUNT个,前

MIDDLE_NODE+1~LARGE_NODE优的局部状态搜索LARGE_NODE_COUNT个。

int last[MaxN][MaxN];

last[i][j]计算第i个炸弹炸第j个目标后,可以持续炸到第多少个目标

7

NOI 2003 全国信息学奥林匹克竞赛试题 解题报告——Day2——Problem3——智破连环阵(Zplhz)

南京市外国语学校 朱泽园

int dis(int x1, int y1, int x2, int y2)

返回坐标距离的平方 void Init()

读入数据并且生成last数组,last生成完毕以后,各对象的坐标等参数都不需要了。

int maxd;

int hash[MaxN], ans[MaxN], now[MaxN];

maxd记录当前最大深度,hash记录被用过的炸弹,now记录当前炸弹序列,ans记录最优炸弹序列(用于输出)

struct TNext {

int v, last; };

记录局部的所有可转移的方案,v表示使用的炸弹编号,last表示可以出炸到多少号目标。

int lower_evaluate(int killed)

A*估值函数,killed为当前炸毁的目标数量,返回至少需要的炸弹数量。

int search(int Large_Node_Count, int Middle_Node_Count, int killed, int used)

当前剩下的使用“次优”和“第三优”局部状态的数量,killed为当前摧毁的目标数,used为当前使用的炸弹数。 void Doit()

主过程,进行深度的叠加 程序清单 (使用1024*768分辨率+Windows Notepad可达到视觉最佳效果)

8

搜索更多关于: Zplhz - 智破连环阵 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

NOI 2003 全国信息学奥林匹克竞赛试题 解题报告——Day2——Problem3——智破连环阵(Zplhz) 南京市外国语学校 朱泽园 深度优先搜索 搜索确实是一种无奈之下的选择,深度优先搜索就是把所有的情况都考虑进去,找出最优的。可以进行的优化有两种: 1、分枝定界、A*搜索。在正式搜索之前,进行一次预先的贪心处理,尽可能地缩小搜索范围。每次将当前状态,以及接下来达到目标所最少需要的炸弹数(估值)相加,如果大于等于当前的最少炸弹数,那么就剪枝。 2、即使这样,遇到了大数据还是铁定超时,为了让程序在时限内出界,可以适当卡结点。就是已经处理的情况数量,大于一个固定值的时候,输出当前较优值并且退出。 可惜这种算法,仍然无法得到一个较好的分值。 宽度优先搜索——IDA*搜索 为了尽可能缩小处理的情况总数,我

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com