2 条题解

  • 0
    @ 2025-11-22 12:21:49

    E44 单调队列优化DP 修剪草坪

    // 单调队列+DP O(n)
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=100010;
    int n,k,w[N],q[N];
    long long f[N],sum;
    
    int main(){
      cin>>n>>k; k++;
      for(int i=1;i<=n;i++) cin>>w[i],sum+=w[i];
      
      long long s=1e18;
      for(int i=1,h=1,t=0; i<=n; i++){
        while(h<=t && q[h]<i-k) h++;
        while(h<=t && f[q[t]]>=f[i-1]) t--;
        q[++t]=i-1;
        f[i]=f[q[h]]+w[i];
        if(i>n-k) s=min(s,f[i]);
      }
      cout<<sum-s;
    }
    
    • 0
      @ 2025-10-8 17:06:28
      #include <bits/stdc++.h>
      using namespace std;
      typedef long long LL;
      const int N = 110000;
      LL a[N], f[N];
      int q[N];
      
      int main() {
          int n, m;
          scanf("%d%d", &n, &m);
          m++;
          LL s = 0;
          for (int i = 1; i <= n; i++) {
              scanf("%lld", &a[i]);
              s += a[i];
          }
          
          int l = 1, r = 1;
          q[1] = 0;
          for (int i = 1; i <= n; i++) {
              while (l <= r && i - q[l] > m) {
                  l++;
              }
              f[i] = f[q[l]] + a[i];
              
              while (l <= r && f[q[r]] >= f[i]) {
                  r--;
              }
              q[++r] = i;
          }
          
          LL t = LL(1) << 60;
          for (int i = n - m + 1; i <= n; i++) {
              t = min(t, f[i]);
          }
          printf("%lld\n", s - t);
          
          return 0;
      }
      
      • 1

      E44*【单调队列】连续长度不超过m个的最大总和[USACO11OPEN] Mowing the Lawn G

      信息

      ID
      4107
      时间
      1000ms
      内存
      128MiB
      难度
      5
      标签
      递交数
      71
      已通过
      26
      上传者