BZOJ_P2442 [Usaco2011 Open]修剪草坪(單調隊列)

BZOJ傳送門

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 690 Solved: 338
[Submit][Status][Discuss]
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 2
1
2
3
4
5

輸入解釋:

FJ有5只奶牛,他們的效率爲1,2,3,4,5。他們希望選取效率總和最大的奶牛,但是他不能選取超過2只連續的奶牛

Sample Output
12

FJ可以選擇出了第三隻以外的其他奶牛,總的效率爲1+2+4+5=12。

HINT

Source
Gold

Sol:
一眼DP,好像斜率優化?
hhhhhhhhh 哪裏來的斜率
居然過樣例了hhhhhhhhh
單調隊列維護一下最小損失就可以了

#include<cstdio>
#define N 100005
#define min(a,b) (a<b?a:b)
inline int in(int  x=0,char ch=getchar()){while(ch>'9'||ch<'0') ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x;}
long long f[N];int n,k,h,t;int q[N],a[N];long long sum,ans;
int main(){
    n=in();k=in();h=t=1;
    for(int i=1;i<=n;i++) a[i]=in(),sum+=a[i];ans=sum;
    for(int i=1;i<=n;i++){
        while(h<t&&q[h]+k+1<i) h++;
        f[i]=f[q[h]]+a[i];
        while(h<=t&&f[i]<=f[q[t]]) t--;
        q[++t]=i;
    }
    for(int i=n-k;i<=n;i++) ans=min(ans,f[i]);
    printf("%lld\n",sum-ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章