NOIP 妙题集锦

NOIP2017 逛公园
k 等于0就是最短路计数,可以拿 30 p t s 30pts 30pts
注意到题目提示我们有0边的情况,如果有0环,且 0 环在1 – n 的某一条长度不超过 d + k d+k d+k 的道路上,那么条数一定有无限条
于是用 t a r j a n tarjan tarjan 缩出 0 边的强连通分量,从起点和终点正着倒着跑一遍最短路
枚举 0 边,通过两边的距离判断
考虑先求出最短路,然后 d p dp dp f i , j f_{i,j} fi,j表示到 i i i,比最短路多 j j j的方案数
转移: f i , j = ∑ f t , j + d i s [ i ] − d i s [ t ] − w [ i ] f_{i,j} =\sum f_{t,j+dis[i]-dis[t]-w[i]} fi,j=ft,j+dis[i]dis[t]w[i], 可以记忆化搜索
a n s = ∑ i = 0 k f n , i ans=\sum_{i=0}^k f_{n,i} ans=i=0kfn,i
NOIP2017 宝藏
考虑状压 d p dp dp,由于最后选出来的是一棵树,我们可以一层层考虑
f s , i f_{s,i} fs,i表示在第 i i i层,选了的集合为 s s s的最小代价
枚举下一层选哪些,也就是下一层的集合
f s ∣ s ′ , i + 1 = f s , i + v a l s , s ′ ∗ i f_{s|s',i+1}=f_{s,i}+val_{s,s'}*i fss,i+1=fs,i+vals,si
v a l s , s ′ val_{s,s'} vals,s表示从 s 走到 s’ 的最小价值,先处理点到集合的最短路径,再处理集合到集合的,可以 4 n 4^n 4n预处理
复杂度 O ( 4 n + n 2 ∗ 3 n ) O(4^n+n^2*3^n) O(4n+n23n)
NOIP2017 列队
我们可以将拿出来的点在线段树打一个标记,这样查询第 x 个就可以在线段树上面二分
最后一列单独开一棵线段树,取出来的点不用一个 vector 存在后面就可以了,线段树用动态开点
NOIP2016 天天爱跑步
将向上向下走的取分开
对于向上走的,如果 d e p s t = d e p u + w u dep_st=dep_u+w_u depst=depu+wu,那么会被看见
那是不是就查一下子树 d e p = d e p u + w u dep = dep_u+w_u dep=depu+wu的点的个数呢?
不,我们发现万一在 l c a lca lca处拐下去了呢,于是需要查分一下,在 f a [ l c a ] fa[lca] fa[lca]处打一个标记
对于向下走的,如果 l e n − d e p e d = w u − d e p u len-dep_{ed}=w_u-dep_u lendeped=wudepu, 那么会被看见,同样查分一下
然后我们发现 l c a lca lca会被算2次,于是向下的标记打到 l c a lca lca
每个dep开一棵线段树,然后动态开点,第二种情况数组需要平移一下
NOIP2016 换教室
比较裸的概率 d p dp dp,加一维换不换就可以解决了,然后预处理直接 f l o y e d floyed floyed
NOIP2016 飞扬的小鸟
预处理经过 2 只或2只以上的鸟的解析式,以及每个解析式打到的鸟的集合 g [ i ] g[i] g[i],剩下的没有统计的只有一个人一个解析式
然后状压, f s ∣ g [ i ] = f s + 1 f_{s|g[i]}=f_s+1 fsg[i]=fs+1
NOIP2016 蚯蚓
巧妙得注意到蚯蚓长度的单调性,就是先被切掉的两段,还是比后切掉的两段长
于是开 3 个队列,每次比对头,就可以避免优先队列的 l o g log log
NOIP2015 子串
f i , j , k , 0 / 1 f_{i,j,k,0/1} fi,j,k,0/1表示到 i,匹配到 j ,匹配了 k 段,当前有没有匹配
转移时看能不能匹配,能匹配的话选不选,第 1 维需要滚动一下
NOIP2015 运输计划
二分答案,然后只考虑 d i s > m i d dis>mid dis>mid的路径,考虑如何 check
我们必须找一条边出现在所有 d i s > m i d dis >mid dis>mid 的路径中,树上差分一下dfs一遍就知道有没有这样的路径
如果有,我们选一个最大的,看一下减了过后有没有 m i d mid mid大就可以了
[NOIP2015] 斗地主
贪心+搜索,口胡一下搜索顺序
首先应该先把出的牌多的给搜了,顺子,连对,飞机,然后四带二对,四带二,炸弹,三带1,三带2
最后贪心出对子,贪心王炸即可
NOIP 2014 解方程
做这种题就是要胆大,如果取模后结果为0,那么很大概率它就是为 0
解法也更是暴力,直接枚举 [ 1 , m ] [1,m] [1,m]的数,然后代进去看结果,代的时候用秦九韶算法可以 O ( n ) O(n) O(n)
NOIP2014 飞扬的小鸟
f i , j f_{i,j} fi,j表示到 ( i , j ) (i,j) (i,j) 的最小步数
f i , j = m i n ( f i − 1 , j + y , f i − 1 , j − x , f i , j − x ) f_{i,j}=min(f_{i-1,j+y},f_{i-1,j-x},f_{i,j-x}) fi,j=min(fi1,j+y,fi1,jx,fi,jx)
如果碰到了管子,就赋值成 i n f inf inf,然后需要特判在天花板卡不死掉不下来的情况
复杂度 O ( n ∗ m ) O(n*m) O(nm)
NOIP2013 花匠
比较巧妙的一道 d p dp dp
是A是B不重要,只要是波浪就行了,于是用 f i , g i f_i,g_i fi,gi记录到i是下降还是上升的最大长度
f i = g i − 1 + 1 ( a i < a i − 1 ) f_i=g_{i-1}+1(a_i<a_{i-1}) fi=gi1+1(ai<ai1)
e l s e : f i = f i − 1 else:f_i=f_{i-1} elsefi=fi1,g 同理
NOIP2013 华容道 好题,单独写 传送门
NOIP2012 疫情控制
二分答案,然后尽量往上跳
开始想的是全部跳到根,但这么一来上去又下来不就走冤枉路了吗
于是有种比较简单的做法是,我们记录一个点很多路径的剩下长度最小的那个拿给我们回退,显然拿最小的来满足自己是最优的
于是把不能覆盖的儿子从大到小排序,将剩余的边从大到小排序,双指针扫一下
如果扫到一个点,从这个点上去过,我们就回退,把大边权留给后面
NOIP2012 开车旅行
很妙很 N i c e Nice Nice 的倍增
直接预处理 A,B 从 i i i 2 j 2^j 2j步走到的点以及经过的路径长度 f i , j f_{i,j} fi,j
然后就是考察对 s e t set set 边界的把控能力了
NOIP2011 观光公交
第一反应 d p dp dp
先转换一些题意,要求最小化 ∑ e d i − s t i = ∑ e d i − ∑ s t i \sum ed_i-st_i=\sum ed_i-\sum st_i edisti=edisti
T i T_i Ti 为到达时间, m x i mx_i mxi 为最大的出发时间
记在 i i i 下车的个数是 c i c_i ci,即最小化 ∑ c i ∗ T i \sum c_i*T_i ciTi
考虑到如果 T i ≤ m x i T_i\le mx_i Timxi 在这之前的加速对后面是没有影响的
可以对前后分开考虑
考虑到一次修改最多就能修改到将后面的某一个 T i T_i Ti正好为 m x i mx_i mxi,在这之后后面的贡献就不会被算了
一次修改的贡献为 ∑ c i \sum c_i ci,而最大次数为 m i n ( T i − m x i ) min(T_i-mx_i) min(Timxi)
类似超级钢琴,贪心+堆来维护,将四元组 [ 1 , n , m i n ( T i − m x i ) , ∑ c i ] [1,n,min(T_i-mx_i),\sum c_i] [1,n,min(Timxi),ci] 放进堆,按 ∑ c i \sum c_i ci 排序
然后取出来后,将区间的 T i T_i Ti 全部减去一个数,从断点左右递归处理再插入堆
复杂度理论上是 O ( k l o g k ∗ n ) O(klogk*n) O(klogkn),但由于每次都找到一个中间的断点,然后两边递归处理,所以区间的总个数不会太多,而且分到后面区间就会比较小
不错的一道题, ∑ e d i − s t i = ∑ e d i − ∑ s t i \sum ed_i-st_i=\sum ed_i-\sum st_i edisti=edisti 的转换极大减小了我们的讨论量
堆 + 贪心的思想也比较常见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值