Codeforces Gym 101173 J. Jazz Journey
来源:互联网 发布:mac终端打开文件 编辑:程序博客网 时间:2024/05/22 10:37
J - Jazz Journey
题意
序列 ak dk tk pk
,每种表示从 O
表示单程,为 R
表示往返(但仅有先用该票搭乘
要求对给定的序列求所需的最小花费。保证必定有解。
解题思路
首先根据
序列为: 1 2 3 1 2 1 3 2 4 1
分堆结果:(1 -> 2) 正向 正向 反向 (2 -> 3) 正向 反向 (1 -> 3) 反向 正向 (2 -> 4) 正向 (1 -> 4) 反向
根据 m 种机票的信息,对每条路线记录四种价格: 正向往返
, 反向往返
, 正向单程
, 反向单程
。
若不存在则默认记为 INF 。
其中应注意四种价格部分存在转换关系,应记录其可能的最低价格,例如:选择正向往返可放弃反向的返程。
对同一条路线,暴力计算三种不同方式的购票方案即可:
只买单程票
优先考虑正向往返票,反向往返票次之,最后单程票
优先考虑反向往返票,正向往返票次之,最后单程票
统计总价格。
代码
#include<bits/stdc++.h>using namespace std;const long long inf = 1ll<< 60;const int D = 300000 + 10;int n, d, m, a[D], mpidx = 0;char tk;vector<bool> trip[D];long long price[D][4];map<pair<int, int>, int> mp;pair<int, int> p;int main(){ scanf("%d %d", &n, &d); for(int i=1;i<=d;i++) scanf("%d", &a[i]); for(int i=1;i<d;i++) { if(a[i] > a[i+1]) p = make_pair(a[i+1], a[i]); else p = make_pair(a[i], a[i+1]); if(mp.find(p) == mp.end()) mp[p] = ++mpidx; trip[mp[p]].push_back(a[i]<a[i+1]?true:false); } for(int i=1;i<=mpidx;i++) for(int j=0;j<4;j++) price[i][j] = inf; scanf("%d", &m); for(int i=1, sk, dk, pk, pos=0, midx;i<=m;i++,pos=0) { scanf("%d %d %c %d", &sk, &dk, &tk, &pk); if(tk == 'O') pos+=2; if(sk > dk) p = make_pair(dk, sk), pos++; else p = make_pair(sk, dk); if(mp.find(p) == mp.end()) continue; midx = mp[p]; price[midx][pos] = min(price[midx][pos], (long long)pk); } long long ans = 0; for(int i=1;i<=mpidx;i++) { if(price[i][0] < price[i][2]) price[i][2] = price[i][0]; if(price[i][1] < price[i][3]) price[i][3] = price[i][1]; if(price[i][2]+price[i][3] < price[i][0]) price[i][0] = price[i][2]+price[i][3]; if(price[i][2]+price[i][3] < price[i][1]) price[i][1] = price[i][2]+price[i][3]; long long tmp[3] = {0, 0, 0}; // 全部单程 for(int j=0;j<trip[i].size();j++) { tmp[0] += price[i][3-trip[i][j]]; if(tmp[0] >= inf) { tmp[0] = inf; break; } } // 优先 正向往返 if(price[i][0] == inf) tmp[1] = inf; else { deque<bool> que; for(int j=0;j<trip[i].size();j++) { if(trip[i][j] == true) que.push_back(true); else { if(!que.empty() && que.back() == true) que.pop_back(), tmp[1] += price[i][0]; else que.push_back(false); } } int cntTrue = 0, cntFalse = 0; while(!que.empty()) cntTrue += que.front(), cntFalse += que.front()?false:true, que.pop_front(); if(price[i][2]+price[i][3] > price[i][1]) { int mx = min(cntTrue, cntFalse); tmp[1] += mx * price[i][1]; cntTrue -= mx, cntFalse -= mx; } tmp[1] += price[i][2] * cntTrue + price[i][3] * cntFalse; } // 优先 反向往返 if(price[i][1] == inf) tmp[2] = inf; else { deque<bool> que; for(int j=0;j<trip[i].size();j++) { if(trip[i][j] == false) que.push_back(false); else { if(!que.empty() && que.back() == false) que.pop_back(), tmp[2] += price[i][1]; else que.push_back(true); } } int cntTrue = 0, cntFalse = 0; while(!que.empty()) cntTrue += que.front(), cntFalse += que.front()?false:true, que.pop_front(); if(price[i][2]+price[i][3] > price[i][0]) { int mx = min(cntTrue, cntFalse); tmp[2] += mx * price[i][0]; cntTrue -= mx, cntFalse -= mx; } tmp[2] += price[i][2] * cntTrue + price[i][3] * cntFalse; } sort(tmp, tmp+3); ans += tmp[0]; } printf("%I64d\n", ans);}
阅读全文
0 0
- Codeforces Gym 101173 J. Jazz Journey
- codeforces-gym-100187-J【dfs】
- Codeforces Gym 101246J Buoys
- Codeforces Gym 100753J Souvenirs
- GYM 100801J Journey to the “The World's Start”
- Codeforces Gym 100342J Triatrip Bitset+枚举
- Codeforces Gym 100814J Game 简单博弈
- Codeforces Gym 100800J Jelly Raid (暴搜)
- CodeForces Gym 100989J Objects Panel (A)
- 【模拟】NEERC15 J Jump (Codeforces GYM 100851)
- Codeforces Gym 100962 J. Jimi Hendrix
- Codeforces gym 101343 J 状压dp
- Codeforces Gym 101142 J. Java2016 (构造)
- Codeforces GYM 100753J: Souvenirs 题解
- codeforces Gym 100187J J. Deck Shuffling dfs
- GYM 100801J Journey to the “The World's Start”【二分+Dp+单调队列】
- 【数位DP】Codeforces Gym 100418J Lucky tickets
- CodeForces Gym 100971J 感觉题意有问题
- mybatis中#{}和${}的区别
- 项目之日期转换
- keil&MDK封装函数到lib中,并在程序中调用lib
- Elasticsearch实战——全文检索架构设计
- 编译原理(八) 算符优先分析法(分析过程的算法和C++实现)
- Codeforces Gym 101173 J. Jazz Journey
- c#方法之 实例方法
- 正则表达式学习
- Hadoop HA高可用集群原理和搭建
- CodeForces
- PHP输出XML到页面的3种方法详解
- java中useDelimiter的使用方法 例题
- 编译原理(九) LR(0)文法分析法(算法描述和C++代码实现)
- 去哪儿-首个重复字符-Java