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 ...
随机推荐
- PAT 1065 - 1068 题解
这次的题目来源是 2013 年 10 月 7 日下午的浙大计算机研究生招生机试题. 这次题目的难度,按姥姥的说法是:『比普通的 PAT 要难了 0.5 个点.我是把自己的题目从 1.0 到 5.0 以 ...
- 冒泡排序 和 选择排序的 区别 python
参考:https://www.cnblogs.com/banana201/p/4928733.html ## 冒泡排序法(Bubblesort) ## 所谓排序法,就是对一组无序的序列进行有序的排序( ...
- Leetcode 328 Contains Duplicate set和map应用
找出数组中重复的数,裸的map和set题 class Solution { public: bool containsDuplicate(vector<int>& nums) { ...
- python win32api 使用小技巧
前些日子,由于需要,用python写了个小插件,通过win32api 访问外部程序的窗口 并且做些小操作. 因为原来对win32api 不怎么熟悉 所以只好求救.群里有个QQ:32034767 唐骁勇 ...
- gitlab 添加文件到新建git库
1. 账号拥有master权限 2.执行操作 git clone git@IP:Group/project.gitcd projecttouch README.mdgit add README.mdg ...
- WPF 遍历DataTemplate(获取所有控件)
原文:WPF 遍历DataTemplate(获取所有控件) 情况1:在设定DataTemplate的Name,并且他是在前台表示时,获取DataTemplate里的指定控件. 方法: http://b ...
- 关于JSON 字段数据的直接查询
最新的pgSQL 对json的支持在进一步加强!虽然我也学了那么点皮毛,但是json数据对于WEB的开发确实很重要,苦苦学习了很长一段时间,不断的关系PGSQL的动向! 好在翻看很多高人的例子和介绍, ...
- WPF 4 Ribbon 开发 之 标签工具栏(Tab Toolbar)
原文:WPF 4 Ribbon 开发 之 标签工具栏(Tab Toolbar) 本篇将开始介绍标签工具栏的开发内容,标签工具栏可以说是Ribbon 的核心部分,应用程序所有的功能特性都会集中 ...
- 基于IdentityServer4的单点登录——Client
以MvcClient项目为例 1.新建项目并添加引用 新建一个asp .net core 2.0的项目引用IdentityModel 2.配置 比之前的控制台客户端多这个步骤,需要配置这个客户端的Cl ...
- C# System.Threading.Timer的使用
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...