列表

详情


NC235478. Ginga Tetsudou no Penguin

描述

https://www.bilibili.com/video/BV1kW41147uB

银河铁道上依次散布着 n 只企鹅。

云浅希望能过从中选出 k 只企鹅,帮助它们登上列车。

因为企鹅的体重不同,让每一只企鹅上车需要花费的钱数也不同。第 i 只企鹅上车需要花费的钱数是 a_i

云浅不希望太多的企鹅被落下,因此她要求每 m 个相邻的企鹅中就至少要有一只企鹅被选中。

也就是说,对于每个 ,在 这段区间中至少存在一只企鹅被选上了列车。

云浅并没有多少钱,她想要你帮她求出最小的花费。保证存在至少一种可能的方案。

输入描述

第一行一个正整数 T 表示数据组数。

对于每组数据:第一行三个正整数 n,m,k

第二行 n 个正整数

输出描述

对于每组数据,输出一行一个正整数表示答案。

示例1

输入:

2
6 2 4
1 1 4 5 1 4
7 2 4
1 9 1 9 8 1 0

输出:

7
10

说明:

对于第一组数据,选择第 1,2,3,5 只企鹅即可。

对于第二组数据,应当选择第 1,3,5,7 只企鹅。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 2402ms, 内存消耗: 5344K, 提交时间: 2022-05-01 11:54:23

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5+5;
ll n, m, k;
ll ans=0,t;
ll a[N];//原数据
ll c[N];
ll f[N];
ll st[N];
inline void wqs(ll x) {
  int l = 0, r = 0;
  st[0]=f[0]=c[0]= 0;
  for(int i=1;i<=n;i++){//每个物体进行遍历
    for(;l<=r&&i-st[l]>m;l++);
      f[i]=f[st[l]]+a[i]-x;
      c[i]=c[st[l]]+1;
      for (;l<=r&&(f[i]<f[st[r]]||(f[i]==f[st[r]]&&c[i]<=c[st[r]]));)r--;
      st[++r] = i;
    }
    for(;l<=r&&st[l]<=n-m;l++);
    ans = f[st[l]];
    t=c[st[l]];
}
int main() {
    int tt;
    cin>>tt;
    while (tt--) {
        cin>>n>>m>>k;
        for (int i = 1; i <= n; i++) cin>>a[i];//输入数组
        ll l = 0, r =1e9, mid;
        while (l+1<r) {
            mid = (l + r) >> 1;
            wqs(mid);
            if (t <= k) l = mid;
            else r = mid;
        }
        wqs(l);
        cout<<ans+1ll*l*k<<endl;
  }
  return 0;
}

上一题