[题解]Yet Another Subarray Problem-DP 、思维(codeforces 1197D)
题目链接:https://codeforces.com/problemset/problem/1197/D
题意:
给你一个序列,求一个子序列 a[l]~a[r] 使得该子序列的 sum(l,r)-k*(r-l+1)/m(向上取整)的值是在所有子序列中最大的,并输出最大值
思路:
法一:动态规划
dp[i][j] 表示序列到i截止,这一轮已经进行了j次取数(j = (len+m-1)%m)
那么dp[i][j]维护的就是起点为 s = i-j+1-m*t (t>=0)这个集合的最优,这样所有的 dp[i][j] 就可以维护以 i 截止的最优答案了
对于当前i更新有两种情况:
第一种是只取当前这个 a[i] 这个在 dp[i][1] 特判即可
第二种是还要取前面的,dp[i][j] 从 dp[i-1][j-1](因为 dp[i-1][j-1] 所维护的s集合和 dp[i][j] 所维护的s集合是一样的)转移即可(注意边界条件)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const ll inf=; int n,m;
ll ans=,dp[][],sum[],a[],k; int main()
{
scanf("%d%d%lld",&n,&m,&k);
for(int i=;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[i]=sum[i-]+a[i];
}
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++) dp[i][j]=-inf;
}
dp[][]=a[]-k;
for(int i=;i<=n;i++)
{
dp[i][]=a[i]-k;
for(int j=;j<=min(i,m);j++)
{
if(j==) dp[i][j]=max(dp[i][j],dp[i-][m]+a[i]-k);
else dp[i][j]=max(dp[i][j],dp[i-][j-]+a[i]);
}
}
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++) ans=max(ans,dp[i][j]);
}
cout<<ans<<endl;
return ;
}
法二:尺取法
多加了一层维护 start_point%m=rnd,进行m次尺取法即可
(在时间够的情况下,搞不清楚当前单调队列弹出几个是最优的,那么就枚举,这样就不用担心前面要弹出什么了,只需在 len%m=0 时判断是否要把起始点重置即可)
即如果当前的和减去 k*t 小于0,那么就重新开始,否则继续加
注意 ans 在每一次向后扩展时都要更新
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=;
ll ans=,n,a[N],m,k; int main()
{
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=;i<=n;i++) scanf("%lld",&a[i]);
for(int rnd=;rnd<=m;rnd++){
ll len=; ll now=;
for(int i=rnd;i<=n;i++){
if(len%m==) if(now-len/m*k<) now=,len=;
now+=a[i]; len++;
ans=max(ans,now-(len+m-)/m*k);
}
}
cout<<ans<<endl;
return ;
}
法三:前缀和
我们可以发现 m 很小,只有10,而当子段长度能整除以 m 的时候,再添加一个才会使得我们多去减一个 k
我们可以让所有位置对 m 取模,分成 0—m-1 这样的剩余系,我们枚举剩余系,以剩余系中的位置作为结尾求最大值
当我们枚举到剩余系i的时候,我们另所有处于剩余系i的位置上的数 -k,之后我们直接扫一遍序列,不断累加并和 0 求最大值,遇到可结束位置时,与答案取最大值并更新答案
这样子我们可以再 O(nm) 的时间复杂度下做出这道题
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5+;
int n,m,k,a[maxn],b[maxn]; int main(){
cin>>n>>m>>k;
for(int i=;i<=n;i++)
cin>>a[i];
ll ans=,s=;
for(int j=;j<m;j++){
for(int i=;i<=n;i++)
if(i%m==j)
b[i]=a[i]-k;
else
b[i]=a[i];
s=;
for(int i=;i<=n;i++){
s=max(s+b[i],0ll);
if(i%m==j)
ans=max(ans,s);
}
}
cout<<ans<<endl;
return ;
}
参考:https://www.cnblogs.com/Forever-666/p/11241525.html、http://blog.leanote.com/post/icontofig/Educational-Codeforces-Round-69
[题解]Yet Another Subarray Problem-DP 、思维(codeforces 1197D)的更多相关文章
- 7月15日考试 题解(链表+状压DP+思维题)
前言:蒟蒻太弱了,全打的暴力QAQ. --------------------- T1 小Z的求和 题目大意:求$\sum\limits_{i=1}^n \sum\limits_{j=i}^n kth ...
- 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 \( ...
- D. Yet Another Subarray Problem 思维 难 dp更好理解
D. Yet Another Subarray Problem 这个题目很难,我比赛没有想出来,赛后又看了很久别人的代码才理解. 这个题目他们差不多是用一个滑动窗口同时枚举左端点和右端点,具体如下: ...
- Educational Codeforces Round 69 D. Yet Another Subarray Problem
Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 题目链接 题意: 求\(\sum_ ...
- Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 【数学+分块】
一.题目 D. Yet Another Subarray Problem 二.分析 公式的推导时参考的洛谷聚聚们的推导 重点是公式的推导,推导出公式后,分块是很容易想的.但是很容易写炸. 1 有些地方 ...
- maximum subarray problem
In computer science, the maximum subarray problem is the task of finding the contiguous subarray wit ...
- UVA11069 - A Graph Problem(DP)
UVA11069 - A Graph Problem(DP) 题目链接 题目大意:给你n个点.要你找出有多少子串符合要求.首先没有连续的数字,其次不能再往里面加入不论什么的数字而不违反第一条要求. 解 ...
- 动态规划法(八)最大子数组问题(maximum subarray problem)
问题简介 本文将介绍计算机算法中的经典问题--最大子数组问题(maximum subarray problem).所谓的最大子数组问题,指的是:给定一个数组A,寻找A的和最大的非空连续子数组.比如 ...
- 【题解】Jury Compromise(链表+DP)
[题解]Jury Compromise(链表+DP) 传送门 题目大意 给你\(n\le 200\)个元素,一个元素有两个特征值,\(c_i\)和\(d_i\),\(c,d \in [0,20]\), ...
随机推荐
- k8s常用笔记
安装docker // 安装docker $ yum install -y docker-ce // 开机启动 && 启动服务 $ systemctl enable docker &a ...
- 相对路径 分类: C# 2015-06-11 15:41 8人阅读 评论(0) 收藏
.绝对路径 绝对路径是指文件在硬盘上真正存在的路径.例如"bg.jpg"这个图片是存放在硬盘的"E:\book\网页布局代码\第2章"目录下,那么 &q ...
- Spring Data Redis实战之提供RedisTemplate
参考: http://www.cnblogs.com/edwinchen/p/3816938.html 本项目创建的是Maven项目 一.pom.xml引入dependencies <depen ...
- ajax_封装函数_步骤1
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...
- 《程序员的呐喊》:一个熟悉多种语言的老程序员对编程语言、开发流程、google的战略等的思考,比较有趣。 五星推荐
作者熟悉二三十种编程语言,写了20多年代码.本书是作者对编程语言.开发流程.google的战略等的思考.比较有趣. 前面部分是作者对编程语言的一些思考.作者鄙视C++, Java,面向对象.比较有趣的 ...
- 在Ubuntu上安装LAMP(Apache、Mysql、Php)
原文地址:https://howtoubuntu.org/how-to-install-lamp-on-ubuntu Ubuntu有很多工具可以帮助我们一键配置LAMP环境,比如tasksel,但这些 ...
- springboot打包成jar文件无法正常运行,解决办法已经找到
1.用intellij idea 创建了一个springboot的项目,前期都运行的好好的,在ide中可以正常运行,但是打包成Jar运行却一直报错. 2.经过不懈探索,终于找到解决办法 3.首先,找到 ...
- Sass-@each
@each 循环就是去遍历一个列表,然后从列表中取出对应的值. @each 循环指令的形式: @each $var in <list> 如果你没有接触过列表,也不要紧,他也非常简单. 在下 ...
- day18 python模块 random time sys os模块
day18 python 一.random模块 取随机整数 import random print(random.randint(1,2)) #顾头顾尾 p ...
- 算法 识别有效ip地址和掩码并做统计
题目描述 请解析IP地址和对应的掩码,进行分类识别.要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类. 所有的IP地址划分为 A,B,C,D,E五类 A类地址1.0.0.0~126.2 ...