zoukankan      html  css  js  c++  java
  • P2627 修剪草坪 [单调队列优化dp]

    修剪草坪

    题目描述见链接 .


    color{red}{正解部分}

    连续的工作的牛不超过 KK ightarrowii 头牛若工作, 则左边与其 相距最近的不工作的牛 坐标范围为 [iK,i][i-K, i] .
    所以可以想到 dpdp, 设 F[i,1/0]F[i, 1/0] 表示前 ii 头牛, 第 ii 头牛 工作/不工作 所能得到的最大价值,
    状态转移:
    F[i,0]=max(F[i1,0],F[i1,1])F[i,1]=max(F[j,0]+sum[i]sum[j])=max(F[j,0]sum[j])+sum[i]      (j[iK,i])F[i, 0] = max(F[i-1, 0], F[i-1, 1])\ F[i, 1] = max(F[j, 0] + sum[i]-sum[j]) = max(F[j,0]-sum[j])+sum[i] (j ∈ [i-K,i])
    其中 F[i,0]sum[j]F[i, 0] - sum[j] 可以使用 单调队列 优化 .


    color{red}{实现部分}

    #include<bits/stdc++.h>
    #define reg register
    typedef long long ll;
    
    const int maxn = 1e5 + 5;
    
    int N;
    int K;
    int A[maxn];
    
    ll sum[maxn];
    ll F[maxn][2];
    
    int main(){
            scanf("%d%d", &N, &K);
            for(reg int i = 1; i <= N; i ++) scanf("%d", &A[i]), sum[i] = sum[i-1] + A[i];
            std::deque <int> Q;
            Q.push_front(0);
            for(reg int i = 1; i <= N; i ++){
                    F[i][0] = std::max(F[i-1][0], F[i-1][1]);
                    int l = std::max(0, i-K);
                    while(!Q.empty() && Q.front() < l) Q.pop_front();
                    if(Q.empty()) F[i][1] = A[i];
                    else F[i][1] = F[Q.front()][0] - sum[Q.front()] + sum[i];
                    while(!Q.empty() && F[Q.back()][0] - sum[Q.back()] <= F[i][0] - sum[i]) Q.pop_back();
                    Q.push_back(i);
            }
            printf("%lld
    ", std::max(F[N][0], F[N][1]));
            return 0;
    }
    
  • 相关阅读:
    fullCalendar改造计划之带农历节气节假日的万年历(转)
    Linked List Cycle
    Remove Nth Node From End of List
    Binary Tree Inorder Traversal
    Unique Binary Search Trees
    Binary Tree Level Order Traversal
    Binary Tree Level Order Traversal II
    Plus One
    Remove Duplicates from Sorted List
    Merge Two Sorted Lists
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822482.html
Copyright © 2011-2022 走看看