BZOJ2442: [Usaco2011 Open]修剪草坪 单调队列优化dp
生活随笔
收集整理的這篇文章主要介紹了
BZOJ2442: [Usaco2011 Open]修剪草坪 单调队列优化dp
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
在一年前贏得了小鎮的最佳草坪比賽后,FJ變得很懶,再也沒有修剪過草坪。現在,
新一輪的最佳草坪比賽又開始了,FJ希望能夠再次奪冠。
然而,FJ的草坪非常臟亂,因此,FJ只能夠讓他的奶牛來完成這項工作。FJ有N
(1 <= N <= 100,000)只排成一排的奶牛,編號為1...N。每只奶牛的效率是不同的,
奶牛i的效率為E_i(0 <= E_i <= 1,000,000,000)。
靠近的奶牛們很熟悉,因此,如果FJ安排超過K只連續的奶牛,那么,這些奶牛就會罷工
去開派對:)。因此,現在FJ需要你的幫助,計算FJ可以得到的最大效率,并且該方案中
沒有連續的超過K只奶牛。
Input
* 第一行:空格隔開的兩個整數N和K
* 第二到N+1行:第i+1行有一個整數E_i
Output
* 第一行:一個值,表示FJ可以得到的最大的效率值。
Sample Input
5 21
2
3
4
5
輸入解釋:
FJ有5只奶牛,他們的效率為1,2,3,4,5。他們希望選取效率總和最大的奶牛,但是
他不能選取超過2只連續的奶牛
Sample Output
12
FJ可以選擇出了第三只以外的其他奶牛,總的效率為1+2+4+5=12。
Solution
設$f[i]$為前$i$頭牛且不選$i$的最大值
那么維護一個前綴和$c$
轉移方程就挺顯然的了
$f[i]=max(f[i],f[j]+c[i-1]-c[j])(j>=i-k-1)$
因為轉移區間一定所以直接拿個單調隊列維護,這個應該挺顯然的
#include <bits/stdc++.h>using namespace std ;#define ll long long #define N 1000100 #define inf (1<<30)int n , k ; ll a[ N ] ; ll f[ N ] , c[ N ] ; int q[ N ] ;int main() {scanf( "%d%d" , &n , &k ) ;for( int i = 1 ; i <= n ; i ++ ) {scanf( "%lld" , &a[ i ] ) ;c[ i ] = c[ i - 1 ] + a[ i ] ;}int l = 1 , r = 2 ;ll ans = 0 ;for( int i = 1 ; i <= n + 1 ; i ++ ) {while( q[ l ] < i - k - 1 ) l ++ ;f[ i ] = max( f[ i ] , f[ q[ l ] ] - c[ q[ l ] ] + c[ i - 1 ] ) ;while( f[ i ] - c[ i ] >= f[ q[ r ] ] - c[ q[ r ] ] && l < r ) r -- ;q[ ++ r ] = i ;ans = max( f[ i ] , ans ) ;}printf( "%lld\n" , ans ) ; }?
轉載于:https://www.cnblogs.com/henry-1202/p/9771817.html
總結
以上是生活随笔為你收集整理的BZOJ2442: [Usaco2011 Open]修剪草坪 单调队列优化dp的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 学习第三部分函数——第一章
- 下一篇: Django之缓存