NOI解题报告【DOC精选】.doc

  1. 1、本文档共6页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
NOI解题报告【DOC精选】

NOI 2004 解题报告 Day0: #1:辉辉的一天(huihui) 数学题,呵呵。 ? #2:姗姗的一天(shanshan) 把区间分成三段,取每段的中点询问,可以确定在哪个区间。 注意处理边界。 ? #3:佳佳的一天(jiajia) 随便做就行了,除了1、2手算最优解以外,其它的best都是n。(稍微加些优化就超过10分了) ? Day1: #1:郁闷的出纳员(cashier) 想过用块状数组,发现O(n√n)的时间复杂度有点勉强。 这道题用静态二叉树。 所谓静态二叉树,与动态二叉树不同的是,动态二叉树一开始是一颗空树,以后不断的往里面加入数(这里的数可以扩展为数据),它的优点是插入的数没有大小限制,但容易退化成链。 当然我们可以用平衡二叉树(Splay,Treap)的方法处理,但编程复杂度就要高很多。 静态二叉树是一开始就建好树的结构,并且在操作过程中不改变树的结构,只改变节点的值,但它要受插入数的范围限制,优点是不会退化。 本题的数自然就是工资,它的范围数量级是1e5的,显然这是可以接受的。 ? 因为要涉及到对工资的整体调整,不妨设一个调整值delta,初始时为0,以后对于整体调整只改变delta的值,而不改变树中数的值。 设当前新加入一个初始工资为v的员工,为了保证树中的数+delta为它目前的值,我们将v-delta插入树中。 这样,不难看出,插入树中的数的范围在[-100000,200000]内。 ? 每个节点记录以下数据: s:该节点所代表的工资值,在初始建树时确定。 cur:拥有该工资值的员工个数,初始时为0。 num:该节点所代表子树上工资的员工总数,初始为0。 ? 插入:二分查找,将路径上的节点的num+1,目标节点的cur+1,复杂度O(logn) 涨工资:修改delta,复杂度O(1)。 降工资:修改delta,同时搜索二叉树,将其中min-delta的节点的cur清0,同时将路径上节点的num-cur,最坏情况下复杂度O(n) 输出第k大的工资:搜索,根据左右子树的num值可以确定目标在哪个子树里,复杂度是O(logn) ? #2:沙丘(dune) 先考虑迷宫无圈,即树形图,那么,如果在每个岔路口都选择右手第一条路(walk 1),遇到死路就折回去(walk 0),则肯定可以遍历完整棵树(玩过RPG走迷宫的应该都知道)。 其实就是DFS。 用链表模拟图的链接情况,就可以求出顶点和边的数目。 现在考虑比较复杂的情况,代圈的迷宫。 对于无向图,如果它还有圈,则在DFS过程中会有后向边,即该边指向一个已经访问的顶点。 这里的问题在于构造一种判断顶点是否已经访问过的方法。 如图,BA为一条后向边,在A放置路标,沿B的父亲节点倒退,那么肯定会到达A,则可以确定BA为后向边。 而同时,为了避免在A走AB边,在确定BA为后向边后,重新走到B点(此时不能直接走AB,因为AB在A的方向不能确定),在B放置路标,再退回A,检查A处未走过的边,其中一条边通向有路标的B,则可以确定AB在A的方向。在以后的DFS过程中不走AB边。 ? 这道题的best还是很宽的,关键在于构造。 ? #3:曼哈顿(manhattan) 这道题和NOI2001的炮兵阵地一样,m和n一个大一个小。 自然,要从m=10来入手。 既然横向的街道最多只有10条,每条街的方向只有两种,即使用最笨的枚举也只有210=1024的枚举量。 既然这样,横向街道的方向直接枚举,将花费记做cost1。 ? 然后是解决纵向街道的问题,设最小的纵向街道花费为cost2: 如图,A为起点,B为终点。 设A到B的横向方向为yy,A到B的纵向方向为xx。 ? 过A、B的横向街道方向与yy相同,此时只要在A、B之间有一条xx方向的街道可以满足从A到B有曼哈顿路。 ? 过A的横向街道与yy相反,过B的横向街道与yy相同,此时过A的纵向街道必须与xx相同。 ? 类似地,此时过B的纵向街道必须与xx相同。 ? 过AB的横向街道都与yy相反,此时过AB的纵向街道必须与xx相同,且AB之间存在一条与yy相同的横向街道。 ? 这样,问题就转换成: 寻找一种最小花费的纵向道路方案,使得其满足一系列类似这样的要求:在某个区间内至少存在一种某方向的纵向街道。 (对于第四种情况的横向街道,只要在横向街道枚举完后检查一下,如果不满足条件就不必计算纵向街道了) 用链表need记录所有的要求,need[i]记录右边界为i的要求,last记录区间的左边界,ss记录该区间要求的方向。 ? 用动态规划解决! 设dp[i,j,k]表示,前i列已确定,当前列的方向为k,与当前列方向相反且在i左侧离i最近的列为j的情况下的最小花费。 v[i,k]表示把i列的街道方向改成k的花费。 dp[i,j,

文档评论(0)

taotao0b + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档