题解/算法 {G - Merchant Takahashi}
@LINK: https://atcoder.jp/contests/abc353/tasks/abc353_g
;
很容易想到一个DP定义: DP(i): 从[0...i]选若干个 且以A[i]为结尾 的最大收益
;
DP[I] = p - t*C; // 自己单独;
FOR_( II, 0, I-1){
DP[I] = max( DP[i], DP[II] - C * abs(T[I] - T[II]) + P[I]);
}
DP优化:
把绝对值优化掉, 如果T[I] >= T[II]
此时为(P[I] - C*T[I]) + (DP[II] + C*T[II])
; (我们要(DP[II] + C*T[II])
d的最大值);
否则为(P[I] + C*T[I]) + (DP[II] - C*T[II])
; 我们要DP[II] - C*T[II]
的最大值;
因为T[?] = [0, 2e5]
, 我们维护区间最大值 MaxMin Ma_less, Ma_greater
, 在[0, T[I]]
里 找Ma_less
的最大值, 在[T[I], N-1]
里找ma_greater
的最大值;
.
比如当前DP, 把DP[i] - C*T[i]
放到Ma_less
里, 把DP[i] + C*T[i]
放到Ma_greater
里面;
// DP[i] = DP[j] - C * abs(T[i] - T[j]) + P[i]
// @IF( T[i] >= T[j]): DP[i] = (P[i] - C*T[i]) + (DP[j] + C*T[j]);
// @ELSE: DP[i] = (P[i] + C*T[i]) + (DP[j] - C*T[j]);
Int64_ N, C, M; cin>> N>>C>>M;
___MinMax_QueryModify_ Ma_less, Ma_greater;
{
vector<Int64_> a( N, -9e18);
Ma_less.Initialize( a.data(), a.size());
Ma_greater.Initialize( a.data(), a.size());
}
Int64_ ANS = 0; // zero
FOR_( m, 0, M-1){
Int64_ t, p; cin>> t>> p; -- t;
Int64_ curDP;
{ // self
curDP = p - t*C; // 注意人最开始在`[0]`位置上;
}
{ // pre
{ // less
auto v = Ma_less.Query_interval( 0, t).Val;
if( v != -9e18){
curDP = std::max( curDP, (p - C * t) + v);
}
}
{ // greater
auto v = Ma_greater.Query_interval( t, N-1).Val;
if( v != -9e18){
curDP = std::max( curDP, (p + C * t) + v);
}
}
}
ANS = std::max( ANS, curDP);
Ma_less.Modify_index( t, curDP + C * t);
Ma_greater.Modify_index( t, curDP - C * t);
}
cout<< ANS;