JZOJ 5415. 【NOIP2017提高A组集训10.22】公交运输
来源:互联网 发布:单片机编程 编辑:程序博客网 时间:2024/05/29 06:43
Description
城市中有一条长度为n的道路,每隔1的长度有一个公交车站,编号从0到n,学校在0号车站的位置。其中每个公交车站(除了n号车站)有两个属性ci和vi,代表从这个公交车站出发的公交车的性质。ci代表这个从i出发的公交车,相邻两个停靠站之间的距离。vi表示每坐1站的花费。
注意,一辆公交车出发后会向n号车站的方向行进。同时,一名乘客只能从起点站上车,但可以从任意停靠站下车。校庆志愿者小Z为了帮助校友查询有关城市交通费用的问题,想知道从0号车站(也就是学校)出发,到达每个公交车站的最小花费,于是他找到了你。
Input
输入的第一行有两个整数,n和maxc。
之后的n行,每行两个整数,分别表示0到n-1号车站的c和v.
Output
输出一行n个整数,其中第i个整数代表从0号车站到i号车站的最小花费,若不能从0号车站到达i号车站,则在i号车站的位置输出-1。
Sample Input
输入1:
1 1
1 1
输入2:
9 5
2 5
5 2
5 14
1 18
4 13
3 17
1 16
1 7
5 4
Sample Output
输出1:
1
输出2:
-1 5 -1 10 -1 15 19 20 33
Data Constraint
对于30%的数据满足,1<=n<=5000
对于60%的数据满足,1<=n<=10^5
对于另20%的数据满足,maxc=1
对于100%的数据满足,1<=n<=10^6,1<=maxc<=10,1<=ci<=maxc,1<=vi<=1000
数据存在梯度。
Hint
样例1说明:从0号车站坐1站地,到达1号车站,花费为1,可以发现这是从0号车站到1号车站的最小花费。
Solution
设
F[i] 表示第i 个点的最优答案,那么显然可以想到:F[i]=min{F[j]+i−jc[j]∗v[j]} 但是这样DP的时间复杂度是
O(N2) ,显然不能AC。看到后面的一串表达式像斜率的形式,但是由于转移距离
c[j] 的限制不能直接斜率优化。于是我们想到分类讨论:按照
c 的值和i mod c 的值维护maxc∗maxc 一个上凸包,用单调栈存储即可。时间复杂度为
O(N) 。
Code
#include<cstdio>#include<vector>using namespace std;const int N=1e6+1,inf=1e9;vector<int>s[11][10];int f[N],c[N],v[N];inline int read(){ int X=0,w=1; char ch=0; while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();} while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar(); return X*w;}inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0');}inline int min(int x,int y){ return x<y?x:y;}inline double get(int x,int y){ if(v[x]==v[y]) return inf; return (double)(f[x]-f[y]-v[x]*(x/c[x])+v[y]*(y/c[y]))/(v[y]-v[x]);}inline int calc(int x,int y){ return f[y]+(x-y)/c[y]*v[y];}int main(){ int n=read(),mc=read(); for(int i=1;i<=n;i++) c[i-1]=read(),v[i-1]=read(),f[i]=inf; for(int i=0;i<n;i++) { int x=c[i],y=i%c[i]; while(!s[x][y].empty() && v[i]<=v[s[x][y][s[x][y].size()-1]]) s[x][y].pop_back(); while(s[x][y].size()>1 && get(i,s[x][y][s[x][y].size()-1])>= get(s[x][y][s[x][y].size()-2],s[x][y][s[x][y].size()-1])) s[x][y].pop_back(); s[x][y].push_back(i); for(int j=1;j<=mc;j++) { y=(i+1)%j; while(s[j][y].size()>1 && calc(i+1,s[j][y][s[j][y].size()-1])>= calc(i+1,s[j][y][s[j][y].size()-2])) s[j][y].pop_back(); if(!s[j][y].empty()) f[i+1]=min(f[i+1],calc(i+1,s[j][y][s[j][y].size()-1])); } } for(int i=1;i<=n;i++) write(f[i]==inf?-1:f[i]),putchar(' '); return 0;}
- JZOJ 5415. 【NOIP2017提高A组集训10.22】公交运输
- 【JZOJ 5415】【NOIP2017提高A组集训10.22】公交运输
- JZOJ5415. 【NOIP2017提高A组集训10.22】公交运输 DP
- JZOJ5415. 【NOIP2017提高A组集训10.22】公交运输
- [JZOJ5415]【NOIP2017提高A组集训10.22】公交运输
- 【NOIP2017提高A组集训10.22】公交运输
- 【NOIP2017提高A组集训10.22】公交运输
- 【JZOJ5415】【NOIP2017提高A组集训10.22】[斜率优化]公交运输
- JZOJ 5410. 【NOIP2017提高A组集训10.22】小型耀斑
- 【JZOJ 5410】【NOIP2017提高A组集训10.22】小型耀斑
- 【JZOJ 5411】【NOIP2017提高A组集训10.22】友谊
- JZOJ 5414. 【NOIP2017提高A组集训10.22】幸运值
- 【JZOJ 5414】【NOIP2017提高A组集训10.22】幸运值
- 【JZOJ 5416】【NOIP2017提高A组集训10.22】密码
- 【JZOJ 5413】【NOIP2017提高A组集训10.22】清兰
- JZOJ 5432. 【NOIP2017提高A组集训10.28】三元组
- 【JZOJ 5432】【NOIP2017提高A组集训10.28】三元组
- JZOJ 5407. 【NOIP2017提高A组集训10.21】Deep
- WIFI模块ESP8266的使用指南(客户端和服务器两种模式建立)
- 字符串
- 2017世界医疗机器人大会早鸟票
- C/C++移位运算符
- 如何在CSDN中从个人主页进入专栏
- JZOJ 5415. 【NOIP2017提高A组集训10.22】公交运输
- Spring Data JPA进阶——Specifications和Querydsl
- 西瓜书《机器学习》课后答案——chapter9 _9.4
- 列表
- maven项目parent pom文件
- 51nod 1174 区间中最大的数(RMQ)
- 回车与换行
- React Native 实现热部署、差异化增量热更新
- java 实体类集合排序