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. 《MySQL实战45讲》学习笔记4——MySQL中InnoDB的索引

    索引是在存储引擎层实现的,且在 MySQL 不同存储引擎中的实现也不同,本篇文章介绍的是 MySQL 的 InnoDB 的索引. 下文将以这张表为例开展. # 创建一个主键为 id 的表,表中有字段 ...

  2. git如何清除远程 __pycahce__ 文件

    第一步,清除已经存在的缓存文件 >> git rm -r -f --cached */__pycache__ rm 'common/__pycache__/__init__.cpython ...

  3. CentOS7安装JAVA环境

    安装JAVA环境我常用的有两种形式 1.下载tar包安装 2.下载rpm包直接安装 本篇内容就写这两种形式的安装方法: JAVA程序的下载地址:https://www.oracle.com/java/ ...

  4. vueCli 运行报错

    error 如下: npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! shopping@0.1.0 serve: `vue-cli-service ...

  5. 【Java】【设计模式 Design Pattern】单例模式 Singleton

    什么是设计模式? 设计模式是在大量的实践中总结和理论化之后的最佳的类设计结构,编程风格,和解决问题的方式 设计模式已经帮助我们想好了所有可能的设计问题,总结在这些各种各样的设计模式当中,也成为GOF2 ...

  6. How Many Answers Are Wrong HDU - 3038 (经典带权并查集)

    题目大意:有一个区间,长度为n,然后跟着m个子区间,每个字区间的格式为x,y,z表示[x,y]的和为z.如果当前区间和与前面的区间和发生冲突,当前区间和会被判错,问:有多少个区间和会被判错. 题解:x ...

  7. windows编译动态链接库,dll+lib的形式

    之前一直在linux上做开发,没怎么关注过windows上如何编译动态链接库.不过一直存疑,为什么windows上的动态链接库是.dll配合.lib使用的,这个又是怎么生成的呢,通过一段时间的查资料和 ...

  8. Gatling脚本编写技巧篇(二)

    脚本示例: import io.gatling.core.Predef._ import io.gatling.http.Predef._ import scala.concurrent.durati ...

  9. 防止html标签转义

    function htmlDecode ( str ) { var ele = document.createElement('span'); ele.innerHTML = str; return ...

  10. vue项目中使用bpmn-基础篇

    内容概述 本系列“vue项目中使用bpmn-xxxx”分为五篇,均为自己使用过程中用到的实例,手工原创,目前属于陆续更新中.主要包括vue项目中bpmn使用实例.应用技巧.基本知识点总结和需要注意事项 ...