盟军敢死队

盟军敢死队(cmdo.pas)
2005 年是第二次世界大战胜利 60 周年,让我们的视线回到战火纷飞的年代„„苏德战争爆发后,苏、美、英 3 国曾多次商讨在西欧开辟第二战场,共同打击法西斯德国的问题。几经周折, 1943 年 11 月,苏、美、英 3 国首脑在德黑兰会议上最终达成协议。 1943 年圣诞节前夕,美国正式宣布任命艾森豪威尔将军为盟军最高司令,统一指挥盟军在西欧的登陆作战。 1944 年初,盟军开始进行登陆作战的准备工作。盟军开辟第二战场的意图是,在法国西北部登陆,夺取登陆场和港口,保障主力上陆和后勤供应,然后发动攻势占领整个法国西北部地区,并与在法国南部登陆的部队配合,向德国内地进攻,协同苏军最后战胜法西斯德国。盟军在比较了 3 处较为合适的登陆地点后认为,在诺曼底地区登陆条件最优越。身经百战的敢死队员们这次接受的是一个看似简单但意义重大的任务:占领诺曼底最大的军火仓库。为了配合即将展开的登陆战,防止德军撤退时摧毁仓库设施,队员们要悄悄的取得仓库的控制权——消灭里面的所有敌人。
显然,敌众我寡,但是对于我们训练有素的队员们来说,这并不是一件困难的事情。
输入(cmdo.in)
仓库是一个 m*n 的矩形区域,每一格用一个字符来描述:“.” 代表空地; “#”代表墙或障碍物; “^” , “v” (小写), “<” , “>” 四个字符分别表示正向 NSWE四个方向看的敌人。敌人总是保持固定不动并朝着一个方向看,从这个方向一直延伸直到边界或障碍物的区域是他的视线范围,如果一个敌人没有在任何人的视线范围之内,敢死队员就可以消灭他。你不能消灭一个正在另一个活着的敌人视
线范围内的敌人,否则你就会被发现,后果不堪设想。一个敌人不会成为遮挡视线的障碍物。
输入数据的第一行是用空格分开的两个整数 n,m ,分别表示仓库的长和宽。
接下来有 n 行,每行 m 个字符,是仓库的描述。
输出(cmdo.out)
  如果能够成功消灭所有敌人,输出消灭所有敌人的不同顺序的数量,否则输出“Impossible”(不含引号)。
样例
Input Output
2 2
>^
#^
2
1 3
>.<
Impossible
约定
100%的数据中, 1<=m, n<=60
90%的数据中,敌人数不超过 10
100%的数据中,敌人数不超过 15

答案看得我满脸问号...

为什么我第一眼看过去就是要连图??

还做得津津有味...

相差了十万八千里的做法...

而且方法数也不知道要怎么算...

那就把每棵树的长度互相乱乘起来当做答案好啦(╯^╰)

不过这样都能骗到40分可见数据有多水了

然而我还是没有做对啊

大概是小错误太多太多的原因改了很久很久很久的主程序

虽然理解思路了但是又写了一个晚自习二进制的做法依然还是没做出来...

扫描二维码关注公众号,回复: 2725131 查看本文章

我恨粗心QAQ

盟军敢死队(cmdo)
解法一:
对每一个敌人赋予一个编号 1~n(n 表示敌人数)
对于表示一个消灭所敌人的顺序的序列 Q,用 p[x]表示敌人 x 在序列中的位置如果敌人 b 在敌人 a 的视线范围内,则必有 p[a]<p[b]
显然,如果对于所有有看守关系的敌人对(a,b)都满足 p[a]<p[b],则序列 Q 是一个合法的消灭敌人的顺序
由此可得算法:
生成 1~n 这 n 个数的全排列
对于每一个排列检查是否对于所有的(a,b)都满足 p[a]<p[b],如果是则 ans
<- ans+1
如果 ans=0,输出"Impossible",否则输出 ans
复杂度 O(n!*n 2)
期望得分 90
解法二:
基于状态压缩的动态规划
推荐使用记忆化搜索的方式实现:
直观、易读
避免计算不必要的状态
使用一个 n 位(bit)的二进制数表示当前已经消灭敌人
如共有 5 个敌人,第4,5 个敌人已经消灭,0/1 分别表示未消灭和已消灭,
则状态为 00011,(00011)2=(3)10,则第 4,5 个敌人已经被消灭的状态表示
为 3
定义 f(x)表示从状态 x 开始,消灭剩余所有敌人的方法数
显然 f(0)即为所求答案:消灭所有敌人的方法数
可以递归地计算函数 f(x):
total <- 0
找出在状态 x 下,剩余的敌人中可以被直接消灭(e.g.不在任何其他敌人
视线范围内)的敌人集合 S
对于每一个敌人 E∈S,将 x 中对应敌人 E 的二进制位置为 1,得到一个
新状态 y(e.g.消灭这个敌人之后的状态),total <- total + f(y)
函数返回 total
特别的,如果 x=2n-1,则函数返回 1(边界条件,表示已经消灭了所有
敌人)
另外:
在递归计算的过程中,计算 f(x)之后,使用一个数组g 将 f(x)的值保存到
g[x]中,当再次调用 f(x)时,则可以直接返回 g[x]的值,以减少计算量。
这样的方式称为记忆化
复杂度:
每个敌人要么已经消灭,要么没有消灭,所以状态的数量为 2n
状态转移复杂度 n2
总复杂度 O(2n*n2)
期望得分 100

猜你喜欢

转载自www.cnblogs.com/GC-hahaha/p/9464990.html