Link
设计出了状态,但没有想到转移
Solution
表示在洗车店区间,最便宜的价格为的最大收入。 一开始想转移的时候,觉得应该是所有经过一段区间的消费者都要算进去,但这样就会有重复 最后发现自己的想法是多么naive 每次转移,只算被区间完全包含的消费者们。 对于枚举到的每个区间,处理,表示经过点而且要求高于的消费者的个数,然后就枚举断点转移就好了。
Code
1 |
|
设计出了状态,但没有想到转移
f[l][r][c]表示在洗车店区间[l,r],最便宜的价格为c的最大收入。 一开始想转移的时候,觉得应该是所有经过一段区间的消费者都要算进去,但这样就会有重复 最后发现自己的想法是多么naive 每次转移f[l][r][c],只算被区间完全包含的消费者们。 对于枚举到的每个区间,处理h[i][c],表示经过点i而且要求高于c的消费者的个数,然后就枚举断点转移就好了。
1 | #include "lucida" |
化简一下式子,比较简单,只用到了等比数列的知识 化简出来之后,发现是当的时候,是几个幂乘一乘加一加,而这些数字都是小于模数的,所以一定与模数互质,用费马小定理优化即可。 有一个坑点: 当a==1的时候,求和的式子里面就没有幂了!所以只能先把n存起来,然后分开讨论!
看一个式子是否满足适用条件,要循环地展开下去查看是否满足
1 | //Code by Lucida |
想到了DP,也想出了状态,也想出了转移,但想不出怎么设置初始值。。
注意:平分不取整。。 f[i][0/1][0/1]表示第i个和第i+1个人分别选他左/右的食物,能否让前i个人满意。 转移就很显然了。 然而因为是个环,初始状态怎么设置? 没有办法,只好取Orz Claris大神,被深深折服了: 依次枚举f[1][0/1][0/1]每一维状态成立,DP完之后看能否满足 这就类似反证法的思路了吧。。假设结论成立,推矛盾。感觉非常地厉害! 我在实现的时候把第n+1个当成第1个,这样只要DP完了,看是否f[n+1][S]==1即可。
这种假设成立,带进去跑的做法比较厉害啊,,有点像的感觉啊,又有点二分答案的感觉啊。。。 好吧,虽说这种枚举答案的做法也不是很少见,但我还是第一次见到放在这一类问题里面。可以记住这个脑洞啊
1 | #include "lucida" |
好吧,又是神题。。
第一步想到了就做出了大半了 设前i个字符中,有b[i]个'B',c[i]个'C',s[i]个'S' 那么只要有位置j,,,,就可以用i−j更新答案了 把变量分离出来,得到三元组 ⟨b[i]−c[i],b[i]−s[i],c[i]−s[i]⟩ 只要保证两个位置的三元组都不相等,就可以了。 第一维排序,第二维树状数组,树状数组维护第三维和位置。 具体说,第一维相同的一起转移,在第二维的树状数组里面维护位置的最大次大和最小次小值,且最值和次值的第三维必须不同,这样就可以查询了。
对于可以用前缀和维护的量,用上前缀和可能会有奇效
1 | #include "lucida" |
就是模拟。。但是居然被细节坑了
Q:这题能有什么细节 A:I am too simple
1 | #include "lucida" |
自己又鼓捣出一个没有卵用的结论
正解: 枚举n判断是否合法,只需要看[lx,rx]和[ly,ry]中是否都存在n的倍数 只需要看(nl−1,nr]是不是空区间即可 一开始不明白为什么不能看[nl,nr],发现l=11,r=15,n=10就是反例
自己的没用结论 看[l,r]中有无n的倍数,需要满足 然后就没办法了
1 | #include "lucida" |
离线,对时间离散化 然后把时间当作横坐标,维护最大最小值 用超神线段树即可
1 | //Code by Lucida |
可以看出,每个点的子树怎么装最快是一个独立的子问题。
所以现在考虑的就是在每个根节点如何安排每个子树的安装顺序
每个子树u最后完成的时间t[u],是进入的时间+f[u]。
而整个子树完成的时间,是max{t[u]}
子树进入的时间是遍历完之前所有子树的时间
一开始的想法是:
如果本身装机时间就长,还要等别的子树,那肯定最后是最慢的?
于是就按照装机时间排序贪心,WA。
考虑一种极端情况:有一个超大的子树,每个点安装的时间都是0,但是遍历很慢,凭此rank1。如果先安装了这个,别的就白等了。
于是启发采用新的策略:按照f[u]−(sz[u]−1)∗2排序,也就是子树安装的时间除去遍历的时间。这样就对了。
具体地说
有一个pair的序列s[],每个s[i]对答案的贡献是s[i].first+j<i∑s[j].second
则Ans=max{s[i].first+j<i∑s[j].second}
设最大值在点u取得,设u与v交换可以使得最大值在v取得且变小
s[u].first+∑s[u′∣u′<u].second
感觉不靠谱。。。能否给个证明。。
如果可能的话,要科学地贪心。 想一些具体的边界情况试着叉掉做法。
1 | #include "lucida" |
如果要把内存分配处理的精细一些还是有点繁的(当然仅仅对我这种juruo) g[]要开两倍。。(好吧我知道地球人都知道但是我刚知道。。)
1 | #include "lucida" |
先计算得到数列 根据字典序最小,肯定要先贪心地取最小的 取了一个数字之后,会增加一个限制条件:路径必须在它的左上方和右下方 所以不停地取合法的,并不停地把条件取交集,直到取满为止
字典序可以优先考虑贪心(SDOI的最小字典序割)
1 | //Code by Lucida |