洛谷P3406 海底高铁(c++,差分,前缀和)

洛谷P3406

        有一说一,对于语言理解能力有问题的本菜鸡来说,理解题意就花了不少时间(手动秃头)。

目录

       1、题意分析

       2、解题思路

        3、AC代码


       1、题意分析

        有n个车站,uim这位悲惨的社畜需要在各个不同的地点(因为不能直达,所以uim一次行动可能要经过多个车站)之间辗转m次。而每段铁路的付费方式分为两种,简单地说就是,不办卡和办卡两种。而其中办卡又需要先交工费c,并且工费不退回,也不能当成卡中余额用来搭车(说白了,就付了几百块,办了张空卡)。当然当然,只让你办空卡,不给你福利是不会有人要去搭车滴。所以,铁路公司就决定让办卡的乘客可以少付一部分车费,也就是只用付b。b一定比直接买票的价格a便宜。               

        现在,我们需要做的就是,帮助uim算出怎么样搭车可以花费最少的钱(一定是公司不给报销,老板真是太可恶了,可怜的uim),并且输出最少的价钱。

       2、解题思路

        因为时间限制为一秒,所以暴力解题肯定是不行滴。题的标签也已经提到了会使用前缀和。然后进一步的思考了一下发现,记录每一段铁路走过的次数,可以使用差分来计算。也就因此进一步,减少了运行时间啦。(好家伙,我发现我的代码里压根儿没有前缀和,救命。算了不管,反正题目的便签上有)。

        其实,该说的注释里也写的差不多了,我就不再多说了。大家直接看代码吧。

        3、AC代码

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
ll num [100010];//每段路去过的次数 

int main () {
	ll N , M , p;//总站台数	会去的站台个数	记录当前所在站台号 
	ll m , t;//前一站台的号码 	比较并交换站台序号的中间量 
	
	scanf("%lld %lld" , &N , &M);
	
	for(ll i = 1 ; i <= M ; i ++) {
		scanf("%lld" , &p);//输入站台次序 
		ll k = p;//方便正序记录下所到的站台序号 
		if(i == 1){
			m = p;
			continue;
		}
		if(m > p){
			t = m;
			m = k;
			k = t;
		}//如果后输入的站台号小 
		num[m] += 1;
		num[k] -= 1;
		m = p;//记录每段路需要经过的次数 
	}
	ll d[100010] , single , car , cost = 0;
	//到过每段路的次数 	买单程票需要的钱 	办卡需要的钱	总钱数 
	ll a , b , c;//该站	  单程票价	IC卡票价	卡费 
	for(ll i = 1 ; i < N ; i ++){//每段路的价钱
		scanf("%lld %lld %lld" , &a , &b , &c);
		d[i] = d[i-1] + num[i];
		single = a * d[i];
		car = b * d[i] + c;
		if(single <= car)cost += single;
		else cost += car;
	}
	
	printf("%lld" , cost);
	
	return 0;
}

注:在上一篇博客里面有写,为什么不使用cin和cout,这里就不多说了。友友们,加油冲冲冲!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值