Educational Codeforces Round 69 D. Yet Another Subarray Problem

Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem

题目链接

题意:

\(\sum_{i=l}^{r}-k\lceil\frac{r-l+1}{m}\rceil\)的最小值,\(n\leq 3*10^5,m\leq 10\)

思路:

因为\(m\)很小,那么对于一段区间,中间部分可以划分为多个长度为\(m\)的区间,两端都长度不超过\(m\)
所以令\(dp(i)\)表示以\(i\)为终点的区间最小值,那么一种情况是它作为区间终点,另一种情况就是其作为中间的一段,分情况转移即可。
代码如下:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 3e5 + 5;
int n, m, k;
ll a[N], sum[N];
ll dp[N];
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n >> m >> k;
    for(int i = 1; i <= n; i++) cin >> a[i], sum[i] = sum[i - 1] + a[i];
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= min(m, i); j++) {
            dp[i] = max(dp[i], sum[i] - sum[i - j] - k);
        }
        if(i >= m) dp[i] = max(dp[i], dp[i - m] + sum[i] - sum[i - m] - k);
    }
    ll ans = 0;
    for(int i = 1; i <= n; i++) ans = max(ans, dp[i]);
    cout << ans;
    return 0;
}

还有一种算法,因为余数比较小,所以就以\(i\)%\(m\)的值分类,然后对于每个余数维护一个前缀最小值。
更新答案时用目前前缀减去所维护的最小值就行了。

转载于:https://www.cnblogs.com/heyuhhh/p/11306747.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值