SPOJ130_Rent your airplane and make money_单调队列DP实现
题意比较简单,状态转移方程也比较容易得出:
f[i]=max{ f [ j ] }+p[i],(j的结束时间在i开始时间之前)
若i开始之前没有结束的j,则f[i]=p[i];
因数据量太大(n<=10000)因此必须优化,这里使用单调队列降低时间复杂度
首先按开始时间排序,队列里存的是编号,队列要求是开始时间严格递增,f[i]利润值严格递增,每次只需维护单调队列,就能将dp部分降到O(n),因插入队列是用到二分查找,所以总的时间为O(nlogn)
维护单调队列的思路:求f[i]时,从队头开始遍历,找到在i开始时间之前最后结束的j,然后将j之前的全部出队,插入时,首先根据i的结束时间二分查找出i可能插入的位置x,然后看该位置之后的f[x]小于等于f[i]的编号x全部删除,然后若i可以放在此处(两种情况:1.空队时,2.f[i]比f[x]小比f[x-1]大时,刚开始这个地方没处理好,WA了n次!!!),则将i插入单调队列。最后求出最大的f[i]即可。
/*************************************************************************
> File Name: A.cpp
> Author: Chierush
> Mail: qinxiaojie1@gmail.com
> Created Time: 2013年07月26日 星期五 10时52分21秒
************************************************************************/ #include <iostream>
#include <cstring>
#include <cstdlib>
#include <set>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <algorithm> #define LL long long
#define LLU unsigned long long using namespace std; struct node
{
int s,t,p;
bool operator<(const node &c) const
{
if (s!=c.s) return s<c.s;
return t<c.t;
}
}; node a[10005];
vector<int>q;
int f[10005]; int find(int x)
{
if (a[q[q.size()-1]].s+a[q[q.size()-1]].t<x) return q.size();
int l=0,r=q.size(),m;
while (l<r)
{
if (l+1==r) return l;
m=(l+r)/2;
if (a[q[m]].s+a[q[m]].t<x) l=m;
else if (a[q[m]].s+a[q[m]].t==x) return m;
else
{
if (m)
{
if (a[q[m-1]].s+a[q[m-1]].t>=x) r=m;
else return m;
}
else return m;
}
}
} int main()
{
int T,n;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
for (int i=0;i<n;++i)
scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].p);
sort(a,a+n);
int ans;
f[0]=ans=a[0].p;
q.clear();
q.push_back(0);
for (int i=1;i<n;++i)
{
while (q.size()>1 && a[q[1]].s+a[q[1]].t<=a[i].s) q.erase(q.begin());
if (a[q[0]].s+a[q[0]].t<=a[i].s) f[i]=a[i].p+f[q[0]];
else f[i]=a[i].p;
int x=find(a[i].s+a[i].t);
while (q.size()>x && f[i]>=f[q[x]]) q.erase(q.begin()+x);
if (!q.size() || (q.size()==x && f[i]>f[q[x-1]]) || (q.size()>x && a[q[x]].s+a[q[x]].t>a[i].s+a[i].t && (!x || f[q[x-1]]<f[i]))) q.insert(q.begin()+x,i);
ans=max(ans,f[i]);
}
printf("%d\n",ans);
}
return 0;
}
SPOJ130_Rent your airplane and make money_单调队列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 ...
- zstu 4237 马里奥的求救——(单调队列DP)
题目链接:http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4237 这题可以转化为每次可以走g~d+x步,求最大分数,且最大分数的步数最少. ...
- 1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP
1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP 题意 用摄像机观察动物,有两个摄像机,一个可以放在奇数天,一个可以放在偶数天.摄像机在 ...
- HDU 5945 维护一个单调队列 dp
Fxx and game Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Tot ...
- vijos P1243 生产产品(单调队列+DP)
P1243生产产品 描述 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产 品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器 ...
- bzoj 1047 : [HAOI2007]理想的正方形 单调队列dp
题目链接 1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2369 Solved: 1266[Submi ...
- POJ 1821 单调队列+dp
题目大意:有K个工人,有n个墙,现在要给墙涂色.然后每个工人坐在Si上,他能刷的最大范围是Li,且必须是一个连续子区间,而且必须过Si,他刷完后能获得Pi钱 思路:定义dp[i][j]表示前i个人,涂 ...
- 【USACO】又买饲料 单调队列dp
题目描述 约翰开车回家,又准备顺路买点饲料了(咦?为啥要说“又”字?)回家的路程一共有 E 公里, 这一路上会经过 N 家商店,第 i 家店里有 F i 吨饲料,售价为每吨 C i 元.约翰打算买 K ...
随机推荐
- SQL Server如何使用OPENQUERY访问另一个SQL Server
在项目中,经常会遇到一个数据库访问另一个数据库,[CNVFERPDB]为服务器名,[CE3]为库名 SELECT Dtl.* FROM CNVFERPDB. CE3.ce3.ZTLE0125 Dtl ...
- ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Razor 编辑表单 上一章节我们介绍了标签助手和 HT ...
- UWP 应用中的Back button(TitleBar) 的处理
后退按钮是一项系统提供的 UI 提示,可以在后退堆栈或用户导航历史记录中支持向后导航. 用起来其实也是很简单的,只需要在App.xaml.cs 中修改(添加)如下红色代码,便可实现.. sealed ...
- Vertica变化Local时间到GMT时间
在Vertica的数据库的使用过程中碰到这么一种场景.程序从不同一时候区的集群中收集数据写入同一张表,然后我们须要把这些数据依照GMT时间来显示. 此时我们能够通过Vertica提供TIME ZONE ...
- maven私服nexus安装
maven私服nexus安装 1.nexus特性 1.1.nexus私服实际上是一个javaEE的web 系统 1.2.作用:用来管理一个公司所有的jar包,实现项目jar包的版本统一 1.3.jar ...
- WPF UpdateSourceTrigger的使用
<Window x:Class="XamlTest.Window8" xmlns="http://schemas.microsoft.com/winf ...
- 在 win10 环境下,设置自己写的 程序 开机自动 启动的方法
原文:在 win10 环境下,设置自己写的 程序 开机自动 启动的方法 1.是登录自己用户时才能开机启 C:\Users\username\AppData\Roaming\Microsoft\Wind ...
- mysql 在不删除数据的时,同时重新更新主键id
1,删除原有主键: ALTER TABLE `table_name` DROP `id`; 2,添加新主键字段:ALTER TABLE `table_name` ADD `id` MEDIUMINT( ...
- 深入理解Amazon Alexa Skill(四)
本节利用三星Smartthings Classic物联网平台的web service smartapp,实现了一个Alexa智能家居skill的例子,由此来了解Alexa是如何控制其他云的智能家居设备 ...
- HTTP请求(GET与POST区别)和响应(get是从服务器上获取数据,post是向服务器传送数据,格式与举例都非常清楚)
HTTP有两部分组成:请求与响应,下面分别整理. 一.HTTP请求 1.HTTP请求格式: <request line> <headers> <blank line> ...