引言:感觉到自己的脑洞确实变大了那么一丢丢。
A、插队——原创By jiedai and nudun
关键字:单调栈,线段树,树状数组
【分析】
题目就是求出每一个点向左数第二个大于它的点的位置。
首先用一个单调递减的单调栈就能求出向左数第一个大于它的点。接下来就比较麻烦了。
如何求出第二个呢?难道再暴力往前for吗?
我的做法仍然是单调栈。对于每一个点,我们都可以知道第一次插队会插到谁那。既然这样,对于一个点,那些第一次插到它的点的关系又会是怎样的?一定是单调递增的!,而且,这些点当然比这个点小。这样按照pos从小到大的顺序在单调栈中查询,不会将前面的有效信息遗漏。
当然这种是比较难想的,大多数人都是用线段树求出第二个大于它的位置。
还有一种树状数组的写法,只是写起来比较麻烦,思路也没有线段树简洁,所以并没有人去写。
B、比赛——CODECHEF SEPT16
关键字:树形dp、倍增
【分析】
比较容易看出是树形dp,但是这个dp比较奇怪,dp转移是从某节点的祖先那里转移过来的。
快速敲完这题就去写第三题了。然后这题就爆炸了。
定义dp[t][u]表示u点往根的路径上$2^t$个点中答案的最小值。那么u点的最小花费就是:
$ans[u]=min(dp[t][F[d-1]],dp[t][F[d-1-k+(1<<t)]])+v)$
转移就比较简单了:
$dp[i][u]=min(dp[i-1][u],dp[i-1][F[d-(1<<i-1)]])$
复杂度$O(n*log(n))$。
【代码】
|
|
C、采油区域——APIO2009
关键字:dp,前缀和
【分析】
首先我们是做过两块区域的。记得当时的思路就是枚举一条将整个区域分成两块的线。
现在是分成三块区域。分成三块区域需要两条线,所以复杂度应该是$O(n^2)$,对于这道题应该是能过的。
三块区域的分布情况有6(4+2)种,而解决这些情况需要5种前缀信息,分别是普通的sum和左上、左下、右上、右下角边长为K的区域石油最多是多少。
接下来就是用sum来$O(n^2)$预处理出其他4个前缀信息,再用$O(n^2)$来从6种情况中更新答案了。
所以这道题对我有点启发,对于一个较难的题目,我们可以先弱化一些条件,在想出解决小问题后试着将同样的思路去解决大问题。
【代码】
|
|