zoukankan      html  css  js  c++  java
  • USACO比赛题泛刷

    随时可能弃坑。
    因为不知道最近要刷啥所以就决定刷下usaco。
    优先级排在学习新算法和打比赛之后。
    仅有一句话题解。难一点的可能有代码。
    优先级是Gold>Silver。Platinum刷不动...(可能有一两道?)

    2015 Feb Gold

    BZOJ3939. [Usaco2015 Feb]Cow Hopscotch

    这题洛谷数据过水,(O(n^4))的dp跑的飞快。。。所以建议在bzoj写。
    但是还是要考虑一下4次方的dp的...其实就是强行枚举转移点,我们可以试着维护前缀和,那么只要倒序枚举m,即有(f[i][j]=sum[i-1][j-1])了。
    但是注意到(sum[i-1][j-1])包含了不能转移的情况,发现相同情况最多(750*750)种,所以可以拿(750*750)个线段树动态开点维护一下就完事了。
    两者相减即为答案,注意第二层要倒序枚举
    当然也是可以cdq分治的。可是我还没学...

    2017 Jan Platinum

    BZOJ4756. [Usaco2017 Jan]Promotion Counting

    想了几种做法...
    主席树(O(nlogn)),线段树合并(O(nlogn)),分块(O(nsqrt{n}log(sqrt{n}))),然而都懒得写...
    然后就写了一个莫队+BIT。(O(nsqrt{n}logn))。离散化一下就行了...
    就是把dfs序爬下来,顺便记录一下siz,那么一个节点的子树在dfs上就是([dfn_x,dfn_x+siz_x-1]),那就用莫队维护一下,每次移动指针对应的在bit里面操作就好了...
    然而在树上直接BIT求逆序对真的没看题解之前不会写(把之前答案删了处理完子树再加上去,这个真的没想到)。

    2016 Open Gold

    LuoguP3145 [USACO16OPEN]分割田地Splitting the Field

    简单套路题...按x值排序之后,枚举分割点求个min就好了,维护y轴坐标的区间max和min,这题可以直接(O(n))处理出来,不过我写了个ST表...
    然后再按y轴排序再来一遍。但是这个完全重合有点奇怪...我把判断删掉才过了...也可能是我判断写错了吧...
    复杂度是(O(nlogn))的。

    BZOJ4579. [Usaco2016 Open]Closing the Farm

    并查集。
    还是挺套路的吧...就是把删边变成连边就好了。
    然后考虑怎么判断。对每个集合维护一个siz,每次合并的时候顺便把siz并起来。
    然后每次把相邻节点merge起来(要判断那个相邻节点是不是还没连上去)。然后再遍历一次,如果有一个的siz不等于当前总节点数,显然就不连通。
    这样复杂度是(O(nlogn))的(只用路径压缩)

    LuoguP3146 [USACO16OPEN]248

    写了一个不同于其他题解的dp。
    (f[l,r,k])表示区间([l,r])合并出(k)是否可行。
    注意到直接枚举转移的话是(O(n^4))的。考虑优化一下。
    因为这样子的dp值是只有0和1的,所以可以拿一个bitset优化一下,就是&一下左右两个子区间然后右移一位就行了。
    至于答案可能不需要把整段并起来这个问题,再开一个bitset,每次对得到的区间或以下就好了。
    这样就能(O(frac{n^4}{w}))搞过去了。

    2017 Jan Gold

    LuoguP3608 [USACO17JAN]Balanced Photo平衡的照片

    很显然的一道题了...离散一下之后用值域BIT维护一下就行了...复杂度是(O(nlogn))

    LuoguP3609 [USACO17JAN]Hoof, Paper, Scissor蹄子剪刀…

    简单dp.设(f[i,j,k])表示前i局,换了j次手势,现在是出第k种手势(0-石头 1-剪刀 2-布)
    然后写个check函数应付一下不换手势的做法就好了。
    分成这轮换手势,这轮不换手势两种转移。(换手势肯定是要换赢的)。
    怎么usaco这么喜欢出dp...

    2016 Dec Gold

    LuoguP3036 [USACO16DEC]Lasers and Mirrors激光和镜子

    搜索。挺好想的,就是不好写...
    仔细研究一下题目,就可以发现几个性质:最优情况下,每个点肯定只会被访问一次,每条边(指网格)也仅会被访问一次。
    所以这样子写个bfs的话是(O(n))的。
    实现方式有很多种...,维护3个vis数组,表示这一行/列有没有访问过,以及这个点有没有被访问过。
    因为坐标有点大,然后可以发现的是只要是相同行的就能走到,所以可以先离散一波。
    然后建两个图,对于每个点,从横坐标向纵坐标连边(另外一个图反着),边权均为1。
    然后从起点开始bfs,对于每个点,拓展没有走过的点(这个点的横/纵坐标之一也必须是没走过的。)
    分类讨论转移即可。细节好多...反正我是重构了3,4次...

    LuoguP2847 [USACO16DEC]Moocast(gold)奶牛广播-金

    同poj2349,改改就好了,跑一遍mst取个最大边权平方即可。

    LuoguP2848 [USACO16DEC]Cow Checklist奶牛确认单

    简单dp。设(f[i][j][0/1])表示目前访问了i头H牛,j头G牛,现在在H牛/G牛处。因为只能顺序访问,所以转移是(O(nm))的,分类讨论一下即可。
    答案是(f[n][m][0])。注意初始化为(f[1][0][0]=0)

    2019 Jan Platinum

    LuoguP5202 [USACO19JAN]Redistricting

    (H)设为1,(G)设为-1,维护一个前缀和。
    显而易见的可以设一个(O(nk))的方程:(f[i] = min{f[i-j]+[s[i]-s[i-j]<=0]}(i-jleq k))
    考虑优化,用个单调队列或者优先队列其实都可以维护。
    单调队列复杂度更优但是难写所以因为太懒我就写了优先队列优化
    对堆中每个点储存两个值,dp值和位置。
    按dp值升序排序,dp值相同按s[i]升序排序。(因为要求min,把那个式子移项一下就可以知道为什么要按s[i]升序了)。
    每次转移时先把距离大于k的点都弹掉(单调性),然后取堆顶(但是不弹出)转移。
    这样就可以(O(nlogk))转移了。

    2019 Jan Gold

    LuoguP5196 [USACO19JAN]Cow Poetry

    需要一点思维(套路)的计数dp以及阅读理解能力。
    反正我是看了很久的题才看懂题意...
    考虑(f[k][j])表示一个长度为k的句子以韵部j结尾。
    显然有转移方程$$f[k][c[i]]=sum{f[k-s[i]][j]}$$
    优化一下就是设$$g[k]=sum{f[k][i]}$$
    然后就可以(f[k][c[i]]=sum{g[k-s[i]]})愉快的(O(nk))转移了。
    然后需要一点计数套路...考虑那些需要押韵的行数对答案贡献。

    [ans=sum{f[K][j]^{cnt[i]}}$$($cnt[i]$为需要压这种韵的行数) 其实就是必须放一样的,那么就用排列算一下就可以知道是这个东西(但是没规定要放哪种,所以取个$sum$)。 乘法原理把每个ans乘起来就好。 (我感觉这个T1其实是三题里面最难的..?) ### LuoguP5200 [USACO19JAN]Sleepy Cow Sorting > 想出来一个结论的话就可以挺顺理成章地把后面想出来了。 **每头牛最多被移动一次**。 其实也挺显然的,因为每次只能移动队头。 考虑什么牛不会被移动,其实就是最后面那段递增序列不用移动。从后往前数第一个不递增的数,1~它全都得移动(因为要把前面的移动了才能移动它)。 而又由上面那个结论可以知道,我们可以在移动的过程中顺便维护出它应该在的位置。这个可以用bit解决。 首先对于每个$j(1leq i leq x)$(x为从后往前数第一个不递增的数),它至少要往后$x-i$头牛(这样才能把x扔到前面),然后考虑把它插入到后面那个递增序列的合适位置,即比它小的数有多少个(这个东西用bit可以很方便的维护)。 那这样的效率就是$O(nlogn)$的了。 ### LuoguP5201 [USACO19JAN]Shortcut > 因为完全忘记了有最短路树这种东西,对这题一脸懵逼,所以看了一下题解之后赶紧滚回去看了czl的课件... 先跑一遍Dijkstra。 因为题目要求字典序最小,那么枚举起点从小的开始枚举,如果枚举到的这条边的两个端点都没连过,那么就可以扔进最短路树里面(因为枚举顺序,如果连过肯定是被更小点连过了,那么字典序会更小)。 然后思路就很显然了。因为是一棵树,加了一条非树边之后显然子树里面都可以不走中间那段了,维护子树的奶牛数量,答案即为: $ans=max{siz[u]*(edge-T)}$ ## 2019 Jan Silver ### LuoguP5199 [USACO19JAN]Mountain View > 偏思维一点的题。 考虑到是等腰直角三角形,所以下面的左端点就是$x-y$,右端点就是$x+y$。 然后按第一关键字左端点升序排序,第二关键字右端点降序排序求解即可。如果右端点大于之前的所有右端点就累加进答案。 ~~至于为什么我觉得有个题解讲的挺好的。~~ ![](https://img2018.cnblogs.com/blog/1113423/201904/1113423-20190401221205973-1881027141.png) ### LuoguP5198 [USACO19JAN]Icy Perimeter > 简单爆搜。将联通块划分出来,那么面积就是最大联通块,然后对每个最大联通块取个周长min就好了。 ### LuoguP5197 [USACO19JAN]Grass Planting > 显然答案是max(度数+1) ## 2017 Dec Gold ### BZOJ5140: [Usaco2017 Dec]A Pie for a Pie > 最短路+set。 这个显然是个最短路问题...,把每个A中B值为0的作为起点往回跑,B中A值为0的作为起点往回跑。每个$a_i$的答案即为它的dis值。 发现边权只有1,所以bfs处理即可。还有一个问题是,边数最大可以到$n^2$,于是我就不会做了。去看了题解的神仙操作:用两个set来维护。 (尽管数据很水,强行连边也跑的飞快。当然这是后面才知道的不然也不会写set做法了...) 首先将每个可能的终点塞进去队列里面,不可能作为终点的就塞进对应的set里面。 每次在set里面二分出来所有可以走的点松弛,松弛完直接删掉(bfs的最优性。)。 所以答案1~n的dis。无解情况将dis初值赋值为-1即可。 这样复杂度是$O(nlogn)$的。 这套其他两题以前做过了。 ## 2018 Feb Gold ### BZOJ5195: [Usaco2018 Feb]Directory Traversal > 换根dp。 一开始看到这题差点以为是大模拟然后直接跑路了。 现在仔细研究了一下其实就是个板子题。 虽然这题题意也有点奇怪就是了:给一棵树,边权是子节点的字符串的长度+1(对于叶子结点的父亲,没有+1) 然后求以某个点为根的每个叶子结点的路径最小和(根自己选)。 那显然就是个换根dp了。 先一次dfs求出以1为根的情况。 然后转移有点特殊: $$f[son]=f[fa]-(siz[son]*(len[son]+1))+(tot_{leaf}-siz[son])*3]

    考虑这个式子的意义:以son节点为根,那对于以son的父亲为根来说,肯定就少了到父亲那一段的引用距离。所以减掉,然后以son为根,那么除了son子树内的叶子结点,其他的叶子结点的路径肯定多了一段:"../",所以*3.(siz指该子树内叶子结点的数量)。
    复杂度(O(n))

    BZOJ5196: [Usaco2018 Feb]Taming the Herd

    dp。一开始没想到能dp...搜了题解看到dp两字滚回去思考了一发差不多就想出来了。
    因为n<=100所以考虑一个(O(n^3))的dp。
    (f[i,j,k])表示前i头牛 出走了j次 当日的真实天数为k。
    那么分类今天有没有出走转移即可。

    [f[i][j][k] = min{f[i-1][j][k-1] + (a[i] != k)}(今天没出走)\ f[i][j][0] = min{f[i-1][j-1][k] + (a[i] != 0)}(今天出走了) ]

    2018Dec Gold

    BZOJ5488: [Usaco2018 Dec]Teamwork

    简单dp。一开始看错题意了...以为分成k组,每组不超过k,然后写了个(O(nk))的单调队列优化dp...
    实际上组数没限制...
    所以可以设(f[i])表示到i的最大价值和。用刷表法转移。
    (f[j]=max(f[j],f[i-1]+(j-i+1)*mx)(r-l+1<=k))
    mx为区间([i,j])的最大值。
    复杂度是(O(nk))的。

    BZOJ5486: [Usaco2018 Dec]Fine Dining

    分层图啥都能干.jpg
    考虑设(d[i][0])表示从n开始走到i的最短路,(d[i][1])表示从n开始走到i经过一个草堆的最短路。
    那么Dijkstra跑一发分层图就好了。也没啥细节。注意分层图分类别分少了就好。

    BZOJ5487: [Usaco2018 Dec]Cowpatibility

    正解是容斥(然而我并不会,只会bitset优化暴力,去找题解学习了一下容斥做法)。
    不过bzoj好像调了时限,然后我现在网上找到的所有容斥题解都TLE了(因为网上的题解都用了string,换成hash才能过)。
    容斥做法:
    显然转化为(n(n-1)/2-)和谐对数。
    然后和谐对数就5种情况:1个一样的,2个一样的,3个一样的,4个一样的,5个一样的。
    用经典的容斥式子:

    [ans=sum_{i=1}^5f(i)*(-1)^i ]

    (f(i))为一样的对数的个数。
    那么(2^5)枚举所有取法,容斥一遍即可。
    用bitset优化一下暴力也跑的飞快,就慢了几百ms。复杂度是小常数的(O(frac{n^2logn}{w}))(要开map不然存不下,或者可以分块求答案就不用开map)。
    代码的话戳这里

    2017Open Gold

    BZOJ4779 [Usaco2017 Open]Bovine Genomics

    https://www.cnblogs.com/henry-1202/p/10631415.html

    BZOJ4780 [Usaco2017 Open]Modern Art 2

    这题看了题解...
    考虑什么情况会是无解?显然就是两条线段不包含而又相交。
    用栈来维护。每次遇到一个新的颜色(这种颜色第一次出现)就入栈。如果到了最后一次出现的地方就弹出。
    那么如果中间有一次遇到一个top和当前颜色不同的,肯定就无解了(如果是包含的,它就会入栈了,没入栈说明一定是相交且不包含。)。
    答案就是top的最大值。(因为每次涂色区域不能相交)
    注意0是不涂色。所以不用管它。

    2017Open Silver

    BZOJ4781 [Usaco2017 Open]Paired Up

    模拟。两个指针扫一扫即可。

    BZOJ4782 [Usaco2017 Open]Bovine Genomics

    枚举三元组。用个桶判三元组在A出现过没有即可。一开始看错题意了...

    BZOJ4783 [Usaco2017 Open]Where

    爆搜。调了1h多调到心态有点炸...
    (O(n^4))枚举矩形。dfs判定。可以先不管覆盖条件,把所有符合条件的矩形找出来,最后(O(n^2))去个重。
    大概80多行...

  • 相关阅读:
    模块
    关于使用 jBox 对话框的提交问题
    Julia is a high-level, high-performance dynamic programming language for technical computing, with syntax that is familiar to users of other technical
    Julia语言:让高性能科学计算人人可用
    [ASP.NET Web API]如何Host定义在独立程序集中的Controller
    ASHX呼叫ASPX.cs的方法
    robotlegs2.0框架实例源码带注释
    指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名(转)
    老板该如何正确的犒赏程序员(转)
    Jass 技能模型定义(转)
  • 原文地址:https://www.cnblogs.com/henry-1202/p/10630330.html
Copyright © 2011-2022 走看看