zstu 4237 马里奥的求救——(单调队列DP)
题目链接:http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4237
这题可以转化为每次可以走g~d+x步,求最大分数,且最大分数的步数最少。
这题的数据范围比较小,可以用奇怪的姿势过。
首先,lyf队长给的方法是n^3的dp过;用我自己的方法是搜索也可以过,因为数据小。
但是,如果数据范围很大,就得用复杂度是O(n)的单调队列dp来做。
上次做过一道单调队列的dp问题,当时比较懵懂,现在,对这个方法有了更深的理解。而且,只要把id丢进单调队列里即可(因为可以通过id查找dp的值)。具体过程还是看代码仔细理解吧:
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
typedef pair<int,int> pii; const int inf =0x3f3f3f3f;
int n,x,g,d;
int a[+];
pii dp[+]; pii solve()
{
deque<int> Q;
dp[]=pii(,);
for(int i=;i<=n;i++)
{
while(!Q.empty() && Q.front()<i-d) Q.pop_front();
if(i-g>= && dp[i-g].first != -inf)
{
while(!Q.empty() && dp[Q.back()] <= dp[i-g]) Q.pop_back();
Q.push_back(i-g);
}
if(!Q.empty()) dp[i] = pii(dp[Q.front()].first + a[i],dp[Q.front()].second - );
//因为题目要求最大分数的最小步数,而对pair的max是默认取大的值,
//所以取个反就是最大化(-步数)
else dp[i] = pii(-inf,);
}
pii ret = pii(-inf,);
for(int i=;i<=n;i++)
{
if(i>=n-d+) ret=max(ret,dp[i]);
//如果处于再跳一步就可以出去的状态的话
}
ret.second = -ret.second + ;
//加1是细节,因为还需要一步跳出
return ret;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&n,&x,&g,&d);
d += x;
for(int i=;i<=n;i++) scanf("%d",a+i);
pii ans = solve();
printf("%d %d\n",ans.first,ans.second);
}
return ;
}
同时,因为pair的比较方法,这里必须把步数转换成负数的。如果不这样就必须写比较器:
bool operator < (const std::pair<int,int> &a,const std::pair<int,int> &b) {
if (a.first != b.first) return a.first < b.first;
return a.second > b.second;
}
bool operator <= (const std::pair<int,int> &a,const std::pair<int,int> &b) {
return a == b || a < b;
}
也可以用写cmp的方式,像sort一样传入第三个参数cmp,同时把dp[Q.back()] <= dp[i-g]改成(max(dp[Q.back()],dp[i-g],cmp) == dp[i-g]) 就行,但是不如上面那样写比较器来的逻辑清晰。
同时,这题有个奇怪的地方在于,重载了以后max还是会出错,必须 if (ret < dp[i]) ret = dp[i];来代替max才行。但是,自己试验了别的代码以后发现,重载了以后max函数是可以生效的,这里真是有毒啊。还是”留坑以后填“吧。。
zstu 4237 马里奥的求救——(单调队列DP)的更多相关文章
- POJ 3017 单调队列dp
Cut the Sequence Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8764 Accepted: 2576 ...
- [TyvjP1313] [NOIP2010初赛]烽火传递(单调队列 + DP)
传送门 就是个单调队列+DP嘛. ——代码 #include <cstdio> ; , t = , ans = ~( << ); int q[MAXN], a[MAXN], f ...
- 1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP
1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP 题意 用摄像机观察动物,有两个摄像机,一个可以放在奇数天,一个可以放在偶数天.摄像机在 ...
- vijos P1243 生产产品(单调队列+DP)
P1243生产产品 描述 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产 品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器 ...
- POJ 1821 单调队列+dp
题目大意:有K个工人,有n个墙,现在要给墙涂色.然后每个工人坐在Si上,他能刷的最大范围是Li,且必须是一个连续子区间,而且必须过Si,他刷完后能获得Pi钱 思路:定义dp[i][j]表示前i个人,涂 ...
- codeforces 1077F2. Pictures with Kittens (hard version)单调队列+dp
被队友催着上(xun)分(lian),div3挑战一场蓝,大号给基佬紫了,结果从D开始他开始疯狂教我做人??表演如何AKdiv3???? 比赛场上:A 2 分钟,B题蜜汁乱计数,结果想得绕进去了20多 ...
- 【LOJ#10180】烽火传递 单调队列+dp
题目大意:给定一个 N 个非负整数数组成的序列,每个点有一个贡献值,现选出其中若干数,使得每连续的 K 个数中至少有一个数被选,要求选出的数贡献值最小. 题解:设 \(dp[i]\) 表示考虑了序列前 ...
- BZOJ 5281--[Usaco2018 Open]Talent Show(分数规划&单调队列&DP)
5281: [Usaco2018 Open]Talent Show Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 79 Solved: 58[Sub ...
- 【CF1077F2】Pictures with Kittens 单调队列+dp
题目大意:给定一个长度为 N 的序列,点有点权,从序列中选出恰好 X 个数,并且保证任意连续的 K 个数中均有一个被选中,求选出的点权最大是多少. 题解:此题可以作为 烽火传递+ 来处理,只不过在烽火 ...
随机推荐
- js文字跑马灯
实现文字跑马灯效果,主要控制scrollLeft. 效果图如下 代码如下 <html> <head> <script type="text/javascript ...
- windows下安装mongoDB(zip版)
windows下安装mongoDB(zip版) 下面说明如何在win10下用zip包安装好mongoDB数据库 首先要先从网上下载mongoDB的zip包 http://dl.mongodb.org/ ...
- linux——环境变量
环境变量 基本概念: 一般是指在操作系统中用来指定操纵系统运行环境的一些参数 当我们用动态库链接成功的时候,其实就是相关的环境变量帮助编译器进行查找. 环境变量通常具有某种特殊用途,还有在系统当中通常 ...
- 使用X.509数字证书加密解密实务(三)-- 使用RSA证书结合对称加密技术加密长数据
一. 使用证书结合对称加密算法加.解密长数据 上一章节讨论了如何使用RSA证书加密数据,文中提到:“Dotnet的RSA实现有个特点,它必须要在明文中添加一些随机数,所以明文不能把128字节占满,实 ...
- sqlserver跨库操作数据
垮库只能读操作,写操作需要设置权限. USE [jdddb] GO /****** Object: StoredProcedure [dbo].[proc_LYOrderCancel] Script ...
- ELinq学习一
ELinq安装:在Nuget控制台中输入:install-package ELinq一.ELinq与DLinq和EF的功能差异 二.数据库对照表 三.CRUD操作1.插入(Insert)(1)简单形式 ...
- scala的泛型浅析
1. scala泛型浅析 package com.dtspark.scala.basics /** * 1,scala的类和方法.函数都可以是泛型. * * 2,关于对类型边界的限定分为上边界和下边界 ...
- Java后端开发常用工具
Java后端开发常用工具推荐: 俗话说,工欲善其事,必先利其器.不过初学时候不大建议过度依赖IDE等过多工具,这会让自己的编程基础功变得很差,比如各种语法的不熟悉,各种关键字比如synchronize ...
- Hadoop_23_MapReduce倒排索引实现
1.1.倒排索引 根据属性的值来查找记录.这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址.由于不是由记录来确 定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(invert ...
- 关于C++ Builder Codegurad 问题的排查。
关于C++ BUILDER6 我目前不知道有什么特别好的内存排查工具.尤其为了对付memory leak, (Eurekalog 这个工具内存泄漏主要针对delphi,BCB配置比较繁琐). 除了BC ...