diff --git a/TangDou/Topic/PrefixAndSuffix/P3406.cpp b/TangDou/Topic/PrefixAndSuffix/P3406.cpp index 32a332a..edb4195 100644 --- a/TangDou/Topic/PrefixAndSuffix/P3406.cpp +++ b/TangDou/Topic/PrefixAndSuffix/P3406.cpp @@ -1,35 +1,31 @@ #include using namespace std; const int N = 100005; -#define int long long +#define int long long // 数据范围是10^5*10^5,所以注意要开ll #define endl "\n" -int p[N]; // 要访问的城市顺序 -int a[N]; // 买票 -int b[N]; // 充值 -int c[N]; // 买卡 -int q[N]; // 差分数组 -int res; +int p[N]; // 要访问的城市顺序 +int x[N], y[N], z[N]; // 买票,充值,买卡 +int b[N]; // 差分数组 +int res; // 结果 +int n, m; // 共n个城市,要去m个城市 -// 数据范围是10^5*10^5,所以注意要开ll signed main() { - int n, m; - cin >> n >> m; - for (int i = 0; i < m; i++) cin >> p[i]; // 记录访问顺序 - for (int i = 1; i <= n - 1; i++) cin >> a[i] >> b[i] >> c[i]; // 输入价格 + cin >> n >> m; // 共n个城市,要去m个城市 + for (int i = 0; i < m; i++) cin >> p[i]; // 访问顺序,下标都是从0开始的 + for (int i = 1; i < n; i++) cin >> x[i] >> y[i] >> z[i]; // 每个城市的买票、充值、买卡价格,此处下标从1开始,是因为P0不需要再到P0 - for (int i = 1; i < m; i++) { // 起点到终点,差分修改 - int t1 = p[i - 1]; - int t2 = p[i]; - if (t1 > t2) - q[t2] += 1, q[t1] -= 1; - else - q[t1] += 1, q[t2] -= 1; + for (int i = 1; i < m; i++) { // 0号点是出发点,没有意义,不讨论,从1号开始,最大是 m-1 + int s = p[i - 1], t = p[i]; // 起点, 终点 + if (s > t) swap(s, t); // 为啥要掉过来呢? + b[s] += 1, b[t] -= 1; // 差分数组处理 } - for (int i = 1; i <= n; i++) q[i] += q[i - 1]; // 前缀和处理 + + for (int i = 1; i <= n; i++) b[i] += b[i - 1]; // 差分数组变形为前缀和数组 // 判断一下 n*a[i]和n*b[i]+c[i]的大小 for (int i = 1; i < n; i++) - res += min(q[i] * a[i], q[i] * b[i] + c[i]); - - cout << res << endl; + res += min(b[i] * x[i], b[i] * y[i] + z[i]); + // b[i]:走几次,x[i]*b[i]:买票需要花费多少钱;b[i] * y[i] + z[i]:办卡+冲值共需要花费多少钱 + // 两个打擂台,谁少就用谁,每一块线段都花费最少,整体必须花费最少,贪心 + cout << res << endl; // 输出 } \ No newline at end of file