【SDOI2008】山贼集团

本文详细介绍了如何将树形问题转化为等效的二叉树问题,并利用动态规划方法求解最优策略。通过设计状态转移方程,实现了一种高效的算法来解决具有复杂数量级的结点选择问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本题的模型是树形状态压缩的动态规划。
首先考虑简单的题目模型:对于任何形态的有根树 T,都可以建立其等效二叉树 T’,若在原树 T 中,结点 x 有儿子c1,c2,c3,,ck,则在二叉树中,与之对应的结点 x’有儿子c1h1h1c2h2以此类推,hk2ck1ck并且所有 hi 都不能建立分部。其他的树的结点的权均有一一对应关系。容易知道在 T 中的最优规划等效于在 T’中的最优规划。

对于二叉树,设计状态 f[n][s]表示以第 n 个结点为根的子数中安排集合 s 的山贼集团分部的最优获利。状态 g[n][s]表示以第 n 个结点为子数不考虑根的安放情况下,安排集合s 的山贼集团分部的最优获利。
易知g[n][s]=maxf[cl][p]+f[cr][sp],其中 cl,cr 为 n 的两个子数,p 为s 的某个子集。
f[n][s]=maxg[n][p]+cost[n][sp]+value[s], 其中 p 为 s 的子集,cost[n][s]表示在结点 n 修建集合 s 的分部所获得的收益, value[s], 表示某个结点相对于集合 s 的收益。

关于上述算法, 最直接的实现是首先使用多叉树转二叉树, 然后直接套用上述递推公式进行计算。其次也可以不转二叉树,而在每个结点的转移处使用嵌套递推的方法。两种方法各有好处,在标程的实现中由于作者习惯采用了二次递推的方法。
在转移处需要枚举某个集合的所有子集, 如果使用直接枚举所有集合然后判断他是不是给定集合的子集,那么复杂度将会是O(n4p),面临超时的危险,下面我们将看到,如果首先预处理出所有集合的子集是哪些的情况下,复杂度将会下降为 O(n3p)

生成c++代码,从代码逻辑角度完善更改 肉鸽生存游戏——武侠客栈 主角:客栈小伙计 游戏主流程: >>主事件(day i=1) * 触发主事件 事件:1. [遇敌](流寇、马匪、山贼、恶僧、无理官兵、侠客切磋、路见不平) 2.[奇遇](观摩高手对决、捡拾物品、顿悟、结交、偷学武学) 3.[收入](发工资-银子、获得武学/生活经验、发现宝藏) * 结算奖励 奖励:1.[战利品](战斗获得奖励) 2.[属性收益](奇遇获得的非物品奖励) 3.[经验收益](人物/武学经验获得) 4.[物品获得](银子、物品、装备、武学、道具) >>进入副事件(5行动点/day) * [领悟](学武学2点) * [练武](增加武学/基本武功经验1点) * [购物](购买商店物品1点) * [交互](与npc互动--交谈、切磋、送礼、请教1点) * [强化](强化装备1点) * [突破](突破武学瓶颈1点) >>结束回合(进入下一天i+1) >>游戏结束 * 人物hp<=0--lose * i>=30--victory 分模块: * 角色状态及属性模块 * 游戏窗口及场景切换模块 * 互动与战斗模块 * 辅助标识模块(物品新旧区分,物品/武侠品质,颜色) * 地图模块 * 经验等级熟练度成长模块 * 刷新模块(商店,任务,状态) * 关卡难度变化模块 * 初始随机模块 * 瓶颈模块(关卡boss,武侠突破,物品强化)
最新发布
05-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值