题目
题目地址
如果没有看懂的话,可以再参考一下这个代佬的博客 木南传送门
题目大意:
uim坐车出差,每过一个站有两种坐车方式,一种是买票,还有一种是刷卡,刷卡的钱肯定比买票的要便宜,但是办卡要花钱,每一个站办的卡只能在那一段铁路使用。我们需要得到uim出一次差花费最少是多少钱
思路
这道题我们可以通过记录通过第i
段铁路的次数,然后比较办卡加刷卡的费用和买票哪个更便宜。
记录通过第i
段铁路的次数可以用差分加前缀和。
代码
#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <queue>
#define ll long long
#define mem(s, i) memset(s, i, sizeof(s))
#define INF 0x3f3f3f3f;
using namespace std;
const int N = 1e5 + 5;
int p[N];
ll ans[N];
//结构体记录通过第i段铁路的各种费用
struct node
{
int a, b, c;
} s[N];
void solve()
{
mem(p, 0);
mem(ans, 0);
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++)
{
scanf("%d", &p[i]);
}
for (int i = 1; i < n; i++)
{
scanf("%d%d%d", &s[i].a, &s[i].b, &s[i].c);
}
//得到从l站到r站通过的站台的次数
for (int i = 1; i < m; i++)
{
ans[min(p[i], p[i + 1])]++;
ans[max(p[i], p[i + 1])]--;
}
for (int i = 1; i <= n; i++)
{
ans[i] += ans[i - 1];
}
ll Sum = 0;
for (int i = 1; i < n; i++)
{
Sum += min(s[i].a * ans[i], (s[i].c + ans[i] * s[i].b));
}
printf("%lld\n", Sum);
}
int main()
{
ios::sync_with_stdio(false);
solve();
return 0;
}