Link!
一次操作可以选择一段连续区间和一个颜色 s 0 s_0 s0,获得 s 0 t 2 s_0t^2 s0t2的收益,其中 t t t是区间内这个颜色出现的个数。
首先观察到取的顺序不影响结果,不妨从左到右取。注意到每次取的区间端点颜色一定一样,否则将不一样的颜色单独出来,显然更优。 设 d p [ i ] dp[i] dp[i]表示取到前 i i i个的最大收益,有转移方程 d p [ i ] = m a x ( d p [ j ] + ( s [ i ] − s [ j ] + 1 ) 2 ) ( c o l [ i ] = = c o l [ j ] ) dp[i] = max(dp[j] + (s[i]-s[j]+1)^2) (col[i] == col[j]) dp[i]=max(dp[j]+(s[i]−s[j]+1)2)(col[i]==col[j]) 对于每种颜色,具有决策单调性,即对于 j 1 < j 2 < i 1 < i 2 j1 < j2 < i1 < i2 j1<j2<i1<i2当一个 j 1 j1 j1转移到 i 1 i1 i1, j 2 j2 j2就不可能转移到 i 2 i2 i2,也就是说决策点是不增的,其原因是二次函数的增长是越来越快的。 于是我们可以用一个单调栈维护最优决策点。 记 f ( x , y ) f(x,y) f(x,y)表示 x x x这个决策点是什么时候优于 y y y的,这个可以二分求出。 如果 f ( S t k t o p − 1 , S t k t o p ) f(Stk_{top-1},Stk_{top}) f(Stktop−1,Stktop)早于当前点 x x x,将 S t k t o p Stk_{top} Stktop弹出,这里会遇到一个问题,如果 S t k t o p − 2 Stk_{top-2} Stktop−2优于 S t k t o p − 1 Stk_{top-1} Stktop−1和 S t k t o p Stk_{top} Stktop但 S t k t o p − 1 Stk_{top-1} Stktop−1劣于 S t k t o p Stk_{top} Stktop,我们便不会弹栈,因此取不到最优决策点。 解决办法就是如果 f ( S t k t o p − 1 , S t k t o p ) < = f ( S t k t o p , x ) f(Stk_{top-1},Stk_{top}) <= f(Stk_{top},x) f(Stktop−1,Stktop)<=f(Stktop,x),就弹栈,因为如果 S t k t o p Stk_{top} Stktop超过了 x x x,那么 S t k t o p − 1 Stk_{top-1} Stktop−1早已超过了他们。 这道决策单调性貌似只能单调栈而不能分治。