欢迎来到endl的博客hhh☀☾☽♡♥

浏览器标题切换
把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

海底高铁(洛谷 P3406)

题目背景

大东亚海底隧道连接着厦门、新北、博艾、那霸、鹿儿岛等城市,横穿东海,耗资1000亿博艾元,历时15年,于公元2058年建成。凭借该隧道,从厦门可以乘坐火车直达台湾、博艾和日本,全程只需要4个小时。

题目描述

该铁路经过N个城市,每个城市都有一个站。不过,由于各个城市之间不能协调好,于是乘车每经过两个相邻的城市之间(方向不限),必须单独购买这一小段的车票。第i段铁路连接了城市i和城市i+1(1<=i<N)。如果搭乘的比较远,需要购买多张车票。第i段铁路购买纸质单程票需要Ai博艾元。

虽然一些事情没有协调好,各段铁路公司也为了方便乘客,推出了IC卡。对于第i段铁路,需要花Ci博艾元的工本费购买一张IC卡,然后乘坐这段铁路一次就只要扣Bi(Bi<Ai)元。IC卡可以提前购买,有钱就可以从网上买得到,而不需要亲自去对应的城市购买。工本费不能退,也不能购买车票。每张卡都可以充值任意数额。对于第i段铁路的IC卡,无法乘坐别的铁路的车。

Uim现在需要出差,要去M个城市,从城市P1出发分别按照P1,P2,P3...PM的顺序访问各个城市,可能会多次访问一个城市,且相邻访问的城市位置不一定相邻,而且不会是同一个城市。

现在他希望知道,出差结束后,至少会花掉多少的钱,包括购买纸质车票、买卡和充值的总费用。

输入格式

第一行两个整数,N,M。

接下来一行,M个数字,表示Pi

接下来N-1行,表示第i段铁路的Ai,Bi,Ci

输出格式

一个整数,表示最少花费

输入输出样例

输入 #1

9 10 3 1 4 1 5 9 2 6 5 3 200 100 50 300 299 100 500 200 500 345 234 123 100 50 100 600 100 1 450 400 80 2 1 10

输出 #1

6394

说明/提示

2到3以及8到9买票,其余买卡。

对于30%数据 M=2

对于另外30%数据 N<=1000 ,M<=1000

对于100%的数据 M,N<=100000,Ai,Bi,Ci<=100000


思想就是简单的差分+前缀和+贪心,然鹅我的代码经过数次修改依然WA了

因此奉上洛谷大佬的代码(大佬不要打我


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #define LL unsigned long long
 6 using namespace std;
 7 int n,m;
 8 LL ans=0,x,y;
 9 long long  a,b,c,p[100001],val[100001];
10 inline long long read(){
11     long long x=0,f=1;
12     char ch;
13     ch=getchar();
14     while (ch<'0'||ch>'9'){
15         if (ch='-')f=-1;
16         ch=getchar();
17     }
18     while (ch>='0'&&ch<='9'){
19         x=x*10+ch-'0';
20         ch=getchar();
21     }
22     return x*f;
23 }
24 inline LL Min(LL x,LL y){
25     if (x<y)return x;
26     else return y;
27 }
28 inline LL Max(LL x,LL y){
29     if (x>y)return x;
30     else return y;
31 }
32 int main(){
33     n=read();
34     m=read();
35     for (register int i=1;i<=m;++i)p[i]=read();
36     memset(val,0,sizeof(val));
37     for (register int i=1;i<m;++i){
38         x=Max(p[i],p[i+1]);
39         y=Min(p[i],p[i+1]);
40         val[y]++;
41         val[x]--;
42     }
43     for (register int i=1;i<=n;++i)val[i]+=val[i-1];
44     for (register int i=1;i<n;++i){
45         a=read();b=read();c=read();
46         ans+=Min(a*val[i],b*val[i]+c);
47     }
48     cout<<ans;
49 }
View Code

不懂的话可以看下这篇文章哟,写的超详细☟☟☟

https://www.cnblogs.com/ljy-endl/p/11325425.html


posted @ 2019-08-10 10:29  endl\n  阅读(267)  评论(0编辑  收藏  举报