妙啊,题出的真的好,虽然没写出来
我们最后一定会经过
我们设
因此我们可以维护一个小根堆堆来使得我们每次的花费最小,设该堆为 heap.top().b < i,那么堆顶弹出,直到heap.top().b >= i,这符合我们之前的第2个条件,又因为我们是边循环边入堆,因此我们的堆中的位置都一定小于
void solve(){
ans = -INF ;
cin >> n ;
_rep(i,1,n){
cin >> a[i] ;
dp[i] = INF ;
}
_rep(i,1,n){
cin >> b[i] ;
}
priority_queue<PII> heap ;
heap.push({-a[1],b[1]}) ;
dp[1] = 0 ;
_rep(i, 2, n){
while(heap.size() && heap.top().second < i) heap.pop() ;
if(heap.size() == 0) break ;
dp[i] = -heap.top().first ;
if(b[i] > i ) heap.push({-(a[i] + dp[i]),b[i]}) ;
}
int sum = 0 ;
_rep(i,1,n){
sum += a[i] ;
ans = max(ans,sum - dp[i]) ;
}
cout << ans << endl ;
}

Comments NOTHING