题意比较简单,状态转移方程也比较容易得出:

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实现的更多相关文章

  1. POJ 3017 单调队列dp

    Cut the Sequence Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8764   Accepted: 2576 ...

  2. [TyvjP1313] [NOIP2010初赛]烽火传递(单调队列 + DP)

    传送门 就是个单调队列+DP嘛. ——代码 #include <cstdio> ; , t = , ans = ~( << ); int q[MAXN], a[MAXN], f ...

  3. zstu 4237 马里奥的求救——(单调队列DP)

    题目链接:http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4237 这题可以转化为每次可以走g~d+x步,求最大分数,且最大分数的步数最少. ...

  4. 1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP

    1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP 题意 用摄像机观察动物,有两个摄像机,一个可以放在奇数天,一个可以放在偶数天.摄像机在 ...

  5. HDU 5945 维护一个单调队列 dp

    Fxx and game Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Tot ...

  6. vijos P1243 生产产品(单调队列+DP)

      P1243生产产品   描述 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产 品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器 ...

  7. bzoj 1047 : [HAOI2007]理想的正方形 单调队列dp

    题目链接 1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2369  Solved: 1266[Submi ...

  8. POJ 1821 单调队列+dp

    题目大意:有K个工人,有n个墙,现在要给墙涂色.然后每个工人坐在Si上,他能刷的最大范围是Li,且必须是一个连续子区间,而且必须过Si,他刷完后能获得Pi钱 思路:定义dp[i][j]表示前i个人,涂 ...

  9. 【USACO】又买饲料 单调队列dp

    题目描述 约翰开车回家,又准备顺路买点饲料了(咦?为啥要说“又”字?)回家的路程一共有 E 公里, 这一路上会经过 N 家商店,第 i 家店里有 F i 吨饲料,售价为每吨 C i 元.约翰打算买 K ...

随机推荐

  1. hexo从零配置next全纪录

    1.按照官网按照hexo: 2.下载next(目前使用的是最新发布版本6.4.1),解压后重命名为next,放在hexo工程themes目录下: 3.网站配置文件_config.yml中,改成them ...

  2. markdownpad 2 的使用

    1. 注册 邮箱:Soar360@live.com 授权秘钥: GBPduHjWfJU1mZqcPM3BikjYKF6xKhlKIys3i1MU2eJHqWGImDHzWdD6xhMNLGVpbP2M ...

  3. Android官方教程翻译(5)——设置ActionBar

    Setting Up the Action Bar 设置Action Bar PREVIOUSNEXT THIS LESSONTEACHES YOU TO 这节课教你 1.    Support An ...

  4. The Python Challenge 题解

    仔细阅读,图画下面的提示(网页的 title 也是重要的提示信息,至少告诉你考察的对象是什么) 1. 238 >> 2**38 274877906944L 根据提示,在 URL 地址处,0 ...

  5. 比较实时分布式搜索引擎(senseidb、Solr、elasticsearch)

    1.它们是基于lucene的. 2.它们分布:sensedb它是multi-write;Solr的shards它是master-slave状态.基于pull策略:elasticsearch的shard ...

  6. (转)react 使用 ref 报错 ,[eslint] Using string literals in ref attributes is deprecated. (react/no-string-refs)

    原文地址:https://www.cnblogs.com/gangerdai/p/7396226.html react 项目中给指定元素加事件,使用到 react 的 ref 属性,Eslink 报错 ...

  7. php_Ubuntu Linux下为PHP5安装cURL,mysql

    如果你在用PHP, 你可能需要用到cURL, 这是其中最流行的插件. PHP CURL插件需要通过libcurl来实现, Daniel Stenberg创建的一个库, 能够和许多不同类型协议的web服 ...

  8. EF延迟加载LazyLoading

    优点 只在需要的时候加载数据,不需要预先计划,避免了各种复杂的外连接.索引.视图操作带来的低效率问题 缺陷:多次与DB交互,性能降低 阻止延迟加载解决方案:1.ToList(),返回的东西是个内存级的 ...

  9. MVC EF 导航属性

    @model IQueryable<EFExam.Models.CategoryProductViewModel>@{    Layout = null;}<!DOCTYPE htm ...

  10. WPF中的多进程(Threading)处理实例(二)

    原文:WPF中的多进程(Threading)处理实例(二) //错误的处理 private void cmdBreakRules_Click(object sender, RoutedEventArg ...