SPOJ130_Rent your airplane and make money_单调队列DP实现
来源:互联网 发布:nodejs读取json文件 编辑:程序博客网 时间:2024/05/22 06:36
题意比较简单,状态转移方程也比较容易得出:
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]即可。
1 /************************************************************************* 2 > File Name: A.cpp 3 > Author: Chierush 4 > Mail: qinxiaojie1@gmail.com 5 > Created Time: 2013年07月26日 星期五 10时52分21秒 6 ************************************************************************/ 7 8 #include <iostream> 9 #include <cstring>10 #include <cstdlib>11 #include <set>12 #include <cstdio>13 #include <string>14 #include <vector>15 #include <map>16 #include <cmath>17 #include <algorithm>18 19 #define LL long long20 #define LLU unsigned long long21 22 using namespace std;23 24 struct node25 {26 int s,t,p;27 bool operator<(const node &c) const28 {29 if (s!=c.s) return s<c.s;30 return t<c.t;31 }32 };33 34 node a[10005];35 vector<int>q;36 int f[10005];37 38 int find(int x)39 {40 if (a[q[q.size()-1]].s+a[q[q.size()-1]].t<x) return q.size();41 int l=0,r=q.size(),m;42 while (l<r)43 {44 if (l+1==r) return l;45 m=(l+r)/2;46 if (a[q[m]].s+a[q[m]].t<x) l=m;47 else if (a[q[m]].s+a[q[m]].t==x) return m;48 else49 {50 if (m)51 {52 if (a[q[m-1]].s+a[q[m-1]].t>=x) r=m;53 else return m;54 }55 else return m;56 }57 }58 }59 60 int main()61 {62 int T,n;63 scanf("%d",&T);64 while (T--)65 {66 scanf("%d",&n);67 for (int i=0;i<n;++i)68 scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].p);69 sort(a,a+n);70 int ans;71 f[0]=ans=a[0].p;72 q.clear();73 q.push_back(0);74 for (int i=1;i<n;++i)75 {76 while (q.size()>1 && a[q[1]].s+a[q[1]].t<=a[i].s) q.erase(q.begin());77 if (a[q[0]].s+a[q[0]].t<=a[i].s) f[i]=a[i].p+f[q[0]];78 else f[i]=a[i].p;79 int x=find(a[i].s+a[i].t);80 while (q.size()>x && f[i]>=f[q[x]]) q.erase(q.begin()+x); 81 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);82 ans=max(ans,f[i]);83 }84 printf("%d\n",ans);85 }86 return 0;87 }
<script type="text/javascript"><!--google_ad_client = "ca-pub-1944176156128447";/* cnblogs 首页横幅 */google_ad_slot = "5419468456";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
- SPOJ130_Rent your airplane and make money_单调队列DP实现
- SPOJ 130 - Rent your airplane and make money(dp+优化)
- SPOJ 130 Rent your airplane and make money
- UVa:1133 Rent your airplane and make money
- COJ - 1005 - Rent your Airplane and make Money 题解
- hdu5945Fxx and game(单调队列+dp)
- hdu 5945 Fxx and Game dp(单调队列优化)
- 【HDU 5945】 Fxx and game 【单调队列优化dp】
- [hdu 5945 Fxx and game] dp+单调队列
- hdu 5945 Fxx and game (dp+单调队列)
- hdu - 5945 Fxx and game 【dp + 单调队列】
- hdu 5945 Fxx and game【dp+单调队列】
- [hdu 5945 Fxx and game] dp+单调队列
- BestCoderRound#89 HDU 5945 Fxx and game【单调队列+DP】
- HDU 5945 Fxx and game [单调队列+dp]【动态规划】
- hdu 5495 Fxx and game(dp+单调队列优化)
- 【HDU 5945】Fxx and game(DP+单调队列)
- hdu 5945 Fxx and game(dp+单调队列)
- [译文]程序员能力矩阵 Programmer Competency Matrix
- jsp中用fileupload组件上传文件遇到的问题
- 求两个字符串的最长公共字串(连续)
- Codeforces Round #194 (Div. 2)总结
- 编写高质量代码:改善C++程序的150个建议(十七)
- SPOJ130_Rent your airplane and make money_单调队列DP实现
- 杭电1016Prime Ring Problem(搜索)
- A. Down the Hatch!
- GDAL读写矢量文件——Java
- 编写高质量代码:改善C++程序的150个建议(十八)
- 单链表的初始化,插入删除等操作
- 关于java中默认字符编码问题
- RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密
- 职场礼仪小摘