2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest Problem J 【二分+DP+单调队列】
2016-09-11 15:04
405 查看
题目链接
(令dp[i]为到第i个站花费的最少时间,d[i]是在该站上下所花时间,r是当前票能够坐的距离)
dp[i]=dp[x]+d[i]+(i−x)
其中 dp[x]=min{dp[i−r]→dp[i−1]}
同时考虑到,我们始终是要从起始站坐到终点站的,又因为往回坐始终不是最优的选择,因此地铁运行所带来的时间花费始终是n-1,因此我们在状态转移的时候不考虑它,而在最后时间加上n-1即可
dp[i]=min{dp[i−r]→dp[i−1]}+d[i]
最终时间为 dp[n−1]+n−1
对于min{dp[i−r]→dp[i−1]},可以用单调队列优化或者直接用线段树,但单调队列在时间上会更优一些。
那么再考虑买哪一种票,首先能够走得更远但价格便宜的票肯定更优,于是先处理一下,去掉价格贵但走不远的票。这样处理后,所有票都会是按照价格递增,距离递增的顺序出现,二分枚举答案即可。
时间复杂度: O(nlog(n))(单调队列) O(nlog2(n)) (线段树)
题意
有n个地铁站,全部成线性排列,有n-1种地铁票,第i种地铁票的价格为p_i,并且能坐i站(也就是在第k个站能够到达[k-i,k+i]中的站)。现在想从起点站坐到终点站,地铁在相邻两个站之间运行花费1s(这里原文是“get from a stop to the next one in just one minute.”有歧义,坑了好久),给出在每个站出来又进去花费的时间,并且从一个站出来又进去后同一张票又可以重新使用,现给定最大的时间花费,求能够到达终点站的票中最便宜的价格。分析
先考虑这样一个问题,假设固定一次最多能坐到的距离,求到终点的最短时间。很容易想到这样的转移方程:(令dp[i]为到第i个站花费的最少时间,d[i]是在该站上下所花时间,r是当前票能够坐的距离)
dp[i]=dp[x]+d[i]+(i−x)
其中 dp[x]=min{dp[i−r]→dp[i−1]}
同时考虑到,我们始终是要从起始站坐到终点站的,又因为往回坐始终不是最优的选择,因此地铁运行所带来的时间花费始终是n-1,因此我们在状态转移的时候不考虑它,而在最后时间加上n-1即可
dp[i]=min{dp[i−r]→dp[i−1]}+d[i]
最终时间为 dp[n−1]+n−1
对于min{dp[i−r]→dp[i−1]},可以用单调队列优化或者直接用线段树,但单调队列在时间上会更优一些。
那么再考虑买哪一种票,首先能够走得更远但价格便宜的票肯定更优,于是先处理一下,去掉价格贵但走不远的票。这样处理后,所有票都会是按照价格递增,距离递增的顺序出现,二分枚举答案即可。
时间复杂度: O(nlog(n))(单调队列) O(nlog2(n)) (线段树)
AC代码
//2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest Problem J. Journey to the “The World’s Start” //AC 2016-9-11 15:02:46 //DP, Binary Search, Monotonic Queue #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cctype> #include <cstdlib> #include <cstring> #include <vector> #include <set> #include <string> #include <map> #include <queue> #include <deque> #include <list> #include <sstream> #include <stack> using namespace std; #define cls(x) memset(x,0,sizeof x) #define inf(x) memset(x,0x3f,sizeof x) #define neg(x) memset(x,-1,sizeof x) #define ninf(x) memset(x,0xc0,sizeof x) #define st0(x) memset(x,false,sizeof x) #define st1(x) memset(x,true,sizeof x) #define INF 0x3f3f3f3f #define lowbit(x) x&(-x) #define input(x) scanf("%d",&(x)) #define inputt(x,y) scanf("%d %d",&(x),&(y)) #define bug cout<<"here"<<endl; //#pragma comment(linker, "/STACK:1024000000,1024000000")//stack overflow #define debug const int maxn=1000100; struct autoque { long long que[maxn]; int index[maxn]; int l; int r; int k; int cur; autoque():l(0),r(0),k(0),cur(0){} autoque(int kk):l(0),r(0),k(kk),cur(0) { memset(que,0,sizeof que); return; } void reset(int kk) { l=0;r=0;k=kk;cur=0; memset(que,0,sizeof que); } long long front() { while(index[l]<cur-k) ++l; return que[l]; } void insert(long long x) { if(l==r) { que[r]=x; index[r++]=cur++; return; } int ll=l,rr=r; int mid; while(rr>=ll) { mid=(ll+rr)/2; if(rr==ll) break; if(x==que[mid]) break; if(x<que[mid]) ll=mid+1; if(x>que[mid]) rr=mid; } que[mid]=x; index[mid]=cur++; r=mid+1; return; } }que; int n; long long t; vector<pair<int,int> > p; int d[50500]; long long dp[50500]; bool valid(int x) { if(x==-1) return 0; dp[0]=0; que.reset(p[x].first); for(int i=1;i<n;++i) { que.insert(-dp[i-1]); dp[i]=-que.front()+d[i]; } return dp[n-1]<=t; } int main() { //ios::sync_with_stdio(false); //cin.tie(0); #ifdef debug freopen("journey.in","r",stdin); freopen("journey.out","w",stdout); #endif //IO cin>>n>>t; t-=(n-1); pair<int,int> pri; for(int i=0;i<n-1;++i) { input(pri.second); pri.first=i+1; while(p.size()&&p.back().second>=pri.second) p.pop_back(); p.push_back(pri); } for(int i=1;i<n-1;++i) input(d[i]); d[n-1]=0; int ans=INF; int l=-1,r=p.size()-1,mid=(l+r)>>1; while(l<r-1) { mid=(l+r)>>1; if(valid(mid)) r=mid; else l=mid; } cout<<p[r].second<<endl; return 0; }
相关文章推荐
- 2015-2016 ACM-ICPC, NEERC, Moscow Subregional Contest H题: Hashing [基础DP]
- 2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest F. Gourmet and Banquet(贪心+二分)
- 【2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest F】【贪心+ STL-优先队列】 Gourmet and Banquet 最大活动时间
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest J】【二分答案+multiset】Journey to the “The World’
- 2015-2016 ACM-ICPC Southwestern Europe Regional Contest (SWERC 15) C题Canvas Painting(单调队列)
- 2015-2016 ACM-ICPC, NEERC, Moscow Subregional Contest K. King’s Rout(拓扑排序)
- 【组队训练】2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest
- 2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D:Distribution in Metagonia(构造)
- CodeForces 589J ——2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest
- 2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Prefer
- 2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest F - Infinite Go
- 2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest J Cleaner Robot
- 2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest A Email Aliases
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest A】【水题 讨论】Alex Origami Squares 矩形内置三个最大正方形
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest B】【构造】Black and White 构造棋盘使得两种棋子联通块数恰为x与y
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest H】【字符串哈希 构造】Hash Code Hacker 构造有相同哈希值的不同字符串
- Gym - 100792A Anagrams (2015-2016 ACM-ICPC, NEERC, Moscow Subregional Contest)
- Codeforces 730 J. Bottles DP 0-1背包- 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest
- 2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest C】【脑洞 本质不同实现的转化】Concatenation A串为前缀B串为后缀不同串