【C++心路历程25】课堂讲义【dp加单调队列】
【问题描述】
高二数学《课堂讲义》总共有n道题目要抄,编号1..n,抄每道题所花时间不一样,抄第i题要花 a[i] 分钟。由于 xxx还要准备IOI,显然不能成天写课堂讲义。xxx决定只用不超过 t 分钟时间抄这个,因此必然有空着的题。每道题要么不写,要么抄完,不能写一半。一段连续的空题称为一个空题段,它的长度就是所包含的题目数。这样应付自然会引起x老师的愤怒。x老师发怒的程度(简称发怒度)等于最长的空题段长度。
现在,xxx想知道他在这 t 分钟内写哪些题,才能够尽量降低x老师的发怒度。由于xxx很聪明,你只要告诉他发怒度的数值就可以了,不需输出方案。
【输入格式】
第一行为两个整数n,t,代表共有n道题目,t分钟时间。
以下一行,为n个整数,依次为a[1], a[2],… a[n],意义如上所述。
【输出格式】
仅一行,一个整数w,为最低的发怒度。
【输入样例】
17 11
6 4 5 2 5 3 4 5 2 3 4 5 2 3 6 3 5
【输出样例】
3
【样例解释】
分别写第4,6,10,14题,共用时 2+3+3+3=11 分钟。空题段:1-3(长为3),5-5(长为1),7-9(长为3),11-13(长为3),15-17(长为3 )。 所以发怒度为3。可以证明,此数据中不存在使得发怒度<=2的作法。
【数据范围】
30%数据 n<=2000,0
void solve()
{int x=1,y=n,ans=n;while(x<=y){int m=(x+y)/2;run(m);long long tmp=//空题段不超过m的情况下,完成题目所需的最小时间;if(tmp>t)//完成不了 x=m+1;else{y=m-1;ans=m;} }printf("%d",ans);
}
现在的关键是处理
tmp,即空题段不超过m的情况下,完成题目所需的最小时间;
这里可以采用dp
方程:
//f(i)表示在前i道题中必选择第i道题做 && 最小空题段数不超过m时 的最小时间
//f(i)=min{f(j) || i-m-1<=j<=i-1}+a[i]
朴素的dp:
//solve30
//f(i)表示在前i道题中必选择第i道题做 && 最小空题段数不超过m时 的最小时间
//f(i)=min{f(j) || i-m-1<=j<=i-1}+a[i] #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const long long inf=40000000000000005;
int n,t;
int a[100005];
long long f[100005];
void run(int m)
{//f(i)=min{f(j) || i-m-1<=j<=i-1}+a[i] f[0]=0;for(int i=1;i<=m;i++)f[i]=a[i];for(int i=m+1;i<=n+1;i++)f[i]=inf; long long t;for(int i=1;i<=n+1;i++){t=inf;for(int j=i-m-1;j<=i-1;j++){t=min(t,f[j]);}f[i]=t+a[i];}
}
void solve()
{int x=1,y=n,ans=n;while(x<=y){int m=(x+y)/2;run(m);long long tmp=f[n+1];//空题段不超过m的情况下,完成题目所需的最小时间;if(tmp>t)//完成不了 x=m+1;else{y=m-1;ans=m;} }printf("%d",ans);
}
int main()
{
// freopen("in.txt","r",stdin);scanf("%d%d",&n,&t);for(int i=1;i<=n;i++)scanf("%d",&a[i]);a[n+1]=0; solve(); return 0;
}
时间复杂度分析:O(n * n *log2 n)
显然不能通过全部数据。
分析方程
f(i)=min{f(j) || i-m-1<=j<=i-1}+a[i]
实际上实在窗口长度为m时找一个f(j)的最小值,因此可以用单调序列优化。
//solve100
void run(int m)
{//f(i)=min{f(j) || i-m-1<=j<=i-1}+a[i] f[0]=0;for(int i=1;i<=m;i++)f[i]=a[i];for(int i=1;i<=n+1;i++)f[i]=inf; long long t;rear=0,front=0;q[rear++]=(data){0,0};for(int i=1;i<=n+1;i++){while(front!=rear && i-q[front].id-1>m) front++;f[i]=q[front].v+a[i];while(front!=rear && q[rear-1].v>f[i]) rear--;q[rear++]=(data){f[i],i};}
}
时间复杂度:O(n*log2 n *log2 n)(每个数据进队一次出队一次)
【C++心路历程25】课堂讲义【dp加单调队列】相关推荐
- 两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 题目大意: 给一棵树,n个节点,每条边有个权值,从每个点i出发有个不经过自己走过的点的最远距离 ...
- Leetcode1696. 跳跃游戏 VI[C++题解]:dp和单调队列求滑动窗口最值
文章目录 题目分析 题目链接 单调队列板子链接 Deque知识补充 题目分析 题目重述:给定一个数组(有正数有负数)和一个步长k,从下标0处开始往前跳,每次最多往前跳k步.求跳到最后一个位置,得分之和 ...
- 浅谈单调队列优化的DP
为什么都是浅谈?深入就掉坑啊,掉坑就要填坑啊,填坑就会发现又挖了更多的坑啊,然后恶性循环啊. 这个坑必须要填的,拖了这么久了. 先拿TYVJ 1305来说吧,此题具体的题面没找到,代码简单的对拍了一下 ...
- ArchSummit微课堂|蘑菇街DevOps实践及心路历程分享
本文整理自 #ArchSummit微课堂#--赵成分享的蘑菇街DevOps实践及心路历程,主要介绍一些运维体系建设中的的经历和实践, 什么是DevOps?为什么是DevOps? 蘑菇街DevOps实践 ...
- 【转】楼天城楼教主的acm心路历程(作为励志用)
[转]楼天城楼教主的acm心路历程(作为励志用) 利用假期空闲之时,将这几年GCJ,ACM,TopCoder 参加的一些重要比赛作个 回顾.昨天是GCJ2006 的回忆,今天时间上更早一些吧,我现在还 ...
- 一位台湾软件工程师的心路历程
发布于2012年12月 前言: 台湾的 IT 环境是什么样的,我们很少关注过.本文作者 superbcde 是一位台湾程序员,他没有显赫的教育背景,从 IT 培训学校开始,一步一步走向自己的奋斗目标. ...
- 前端证券项目_非科班二本前端大厂面试的心路历程和总结(腾讯、头条、阿里、京东)...
现状和背景 个人背景 我是17年毕业的,大三升大四的暑假期间开始学习前端:在这之前一直在小公司打滚:而且至今已经换了四家公司了(算上接下来入职的公司),可谓跳槽非常频繁(其实是小公司容易倒闭).如果说 ...
- LienJack-2年前端面试心路历程(字节跳动、YY、虎牙、BIGO)
LienJack-2年前端面试心路历程(字节跳动.YY.虎牙.BIGO) 大厂面经 字节跳动 1 面 对 tree-shaking 的了解 虽然生产模式下默认开启,但是由于经过 babel 编译全部模 ...
- 【ICPC 2021 沈阳站】心路历程·总结分析
ICPC 2021(沈阳)心路历程·总结分析 战果 前期准备 ①行程问题(时间留余) ②物资准备(板子.证件) ③饮食作息 热身赛 正式赛 战果 本次线下比赛打铁,与牌子挥之交臂,相处一年的阵容,最后 ...
最新文章
- C# 自定义 implicit和explicit转换
- 肝!一行 Python 代码实现并行
- 推荐系统算法-Apriori
- PageHelper概述与基本使用步骤介绍
- 话里话外:冯军的担心 “pk” 流程规范化
- Calico搭建配置
- 一步一步写算法(之排序二叉树删除-2)
- 微软全球资深副总裁张亚勤先生力作——《变革中思索》连载
- 【滤波器】基于matlab GUI高通+低通+带通+带阻FIR滤波器设计【含Matlab源码 092期】
- python读取二进制文件,转成十六进制格式
- LeetCode Golang 答案
- 台式机显示屏作为笔记本显示屏的设置
- 对图像作LUT处理是什么意思
- 别再鼓吹神通广大的黑客了 只有务实才能让高管和董事会加大网络安全投入
- Android-Dex分包最全总结:含Facebook解决方案,移动app开发
- 软考信息系统监理师:2016年4月1日作业
- EA周报 | 字节跳动上线搜索引擎;电影《哪吒之魔童降世》累计综合票房破15亿;鸿蒙系统首发设备欲屏蔽开机广告...
- zabbix监控配置QQ邮箱服务
- 新书出版了(文末送书)
- 视频转为GIF怎么做 如何做GIF动态图