D. Yet Another Subarray Problem

这个题目很难,我比赛没有想出来,赛后又看了很久别人的代码才理解。

这个题目他们差不多是用一个滑动窗口同时枚举左端点和右端点,具体如下:

首先枚举0~m,这个是说更新的位置,如果是1 当m==3 就更新1 4 7 10...

如果是2,当m==3 就更新 2 6 8 11....

最后都会被更新的。

核心代码

 for (int j = ; j < n - i; ++j) {
s += sum[j];
if (j % m == ) s -= k;//这个在判断是不是经过了一个区间,如果经过了就-k
ans = max(ans, s - MIN);//这个是在判断这个时候枚举的区间左端点和区间右端点是不是可以更新答案
if (j % m == m - ) MIN = min(MIN, s);//这个就是在更新区间左端点,只有特定的时刻才可以更新,
//只有在区间左端点才可以,因为我要更新的是下一个区间的右端点,如果提前更新了,那么就会被提前用,可能更新不该更新的东西。
//左端点是由s来更新的,所以不需要考虑k的问题,
//这个左端点只有特定时候才可以更新,因为我们枚举了每一个区间为m的起点,意思就是说我们确定了每一个区间
//当j%m==m-1就是说到了区间的右端点,只有这个时候才可以更新,因为这个时候和我们想更新的是下一个区间的右端点,
//所以这个才满足两点之间相隔了若干个k,这样子就可以一 前缀相减+k的个数相减*k。
}
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
const int maxn = 3e5 + ;
typedef long long ll;
ll n, m, ans, k, a[maxn], sum[maxn]; int main()
{
ans = ;
scanf("%lld%lld%lld", &n, &m, &k);
for (int i = ; i < n; i++) scanf("%lld", &a[i]);
for(int i=;i<m;i++)//枚举第一个区间的起点
{
for (int j = i; j < n; j++) sum[j - i] = a[j];
ll mins = , s = ;
for(int j=;j<n-i;j++)
{
s += sum[j];
if (j%m == ) s -= k;
ans = max(ans, s - mins);
if (j%m == m - ) mins = min(mins, s);
}
}
printf("%lld\n", ans);
}

后来上网看了题解发现这个题目还可以用dp写,感觉dp好理解很多。

dp[i][j] 表示前以 i 为右端点,对m取余为 j 时的最大值。

所以转移方程就很好写了

j== 0  dp[i][j]=max(dp[i-1][m-1]+a[i]-k,a[i]-k)

j!=0 dp[i][j]=dp[i-1][j-1]+a[i]

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<sstream>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 3e5 + ;
ll dp[maxn][];
ll a[maxn];
 
int main()
{
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for (int i = ; i <= n; i++) scanf("%lld", &a[i]);
for(int i=;i<=n;i++)
{
for (int j = ; j < m; j++) dp[i][j] = -inf64;
}
dp[][m - ] = ;
ll ans = ;
for(int i=;i<=n;i++)
{
for(int j=;j<m;j++)
{
if (j == ) dp[i][j] = max(dp[i - ][m - ] + a[i] - k, a[i] - k);
else dp[i][j] = dp[i - ][j - ] + a[i];
ans = max(ans, dp[i][j]);
}
}
printf("%lld\n", ans);
return ;
}

dp

D. Yet Another Subarray Problem 思维 难 dp更好理解的更多相关文章

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

    D. Yet Another Subarray Problem You are given an array \(a_1, a_2, \dots , a_n\) and two integers \( ...

  2. Educational Codeforces Round 61 F 思维 + 区间dp

    https://codeforces.com/contest/1132/problem/F 思维 + 区间dp 题意 给一个长度为n的字符串(<=500),每次选择消去字符,连续相同的字符可以同 ...

  3. Educational Codeforces Round 69 D. Yet Another Subarray Problem

    Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 题目链接 题意: 求\(\sum_ ...

  4. maximum subarray problem

    In computer science, the maximum subarray problem is the task of finding the contiguous subarray wit ...

  5. 动态规划法(八)最大子数组问题(maximum subarray problem)

    问题简介   本文将介绍计算机算法中的经典问题--最大子数组问题(maximum subarray problem).所谓的最大子数组问题,指的是:给定一个数组A,寻找A的和最大的非空连续子数组.比如 ...

  6. ZOJ Problem Set - 3822Domination(DP)

    ZOJ Problem Set - 3822Domination(DP) problemCode=3822">题目链接 题目大意: 给你一个n * m的棋盘,每天都在棋盘上面放一颗棋子 ...

  7. Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 【数学+分块】

    一.题目 D. Yet Another Subarray Problem 二.分析 公式的推导时参考的洛谷聚聚们的推导 重点是公式的推导,推导出公式后,分块是很容易想的.但是很容易写炸. 1 有些地方 ...

  8. 【HDU 5233】Tree chain problem (树形DP+树剖+线段树|树状数组)最大权不相交树链集

    [题目] Tree chain problem Problem Description Coco has a tree, whose vertices are conveniently labeled ...

  9. CodeForces 1197D Yet Another Subarray Problem

    Time limit 2000 ms Memory limit 262144 kB Source Educational Codeforces Round 69 (Rated for Div. 2) ...

随机推荐

  1. re模块语法—python正则表达式

    用字符串匹配实现 对于简单的匹配查找,可以通过字符串匹配实现,比如:查找以”hello”开头的字符串 此时就可以正确查找出以start开始的字符串了 python中的正则表达式模块 在python中为 ...

  2. pomelo环境配置(windows环境)

    目录 简介 准备 安装 工程的创建 简介 1.网易开源,免费,业(diao)界(si)良(fu)心(li)呀,^.^ 2.游戏服务器框架(当然也可以用于web服务器) 3.高性能.高可伸缩.分布式,多 ...

  3. 【LeetCode】 99. Recover Binary Search Tree [Hard] [Morris Traversal] [Tree]

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  4. Laravel joinSub 子查询的写法

    $subQuery = $model::query() ->from('table1 as a') ->getQuery(); $query = $model::query() -> ...

  5. [转+自]SSH工作原理

    SSH工作原理 熟悉Linux的人肯定都知道SSH.SSH是一种用于安全访问远程服务器的网络协议.它将客户端与服务端之间的消息通过加密保护起来,这样就无法被窃取或篡改了.那么它安全性是如何实现的呢? ...

  6. Django文档阅读-Day2

    Django文档阅读 - Day2 Writing your first Django app, part 1 You can tell Django is installed and which v ...

  7. SpringMVC转发及重定向

    基础环境搭建请参考SringMVC入门程序 1:springmvc-servlet.xml <?xml version="1.0" encoding="UTF-8& ...

  8. TeamViewer11 万全免费

    下载地址:百度网盘 c4xm TeamViewer 是一款简单易用且功能强大的远程控制软件,它能穿越内网,摆脱路由器或防火墙的限制,任何一方都不需要拥有固定IP地址.让不懂技术的朋友也能远程控制电脑, ...

  9. pytorch LSTM情感分类全部代码

    先运行main.py进行文本序列化,再train.py模型训练 dataset.py from torch.utils.data import DataLoader,Dataset import to ...

  10. Flutter 开发填坑指南

    引言 第一次在使用Flutter是在Ubuntu机器上,但是因为Android Studio还有Sdk配置问题,flutter doctor总是在这一步报错...最近又在win10上配了一下环境(真香 ...