旅行
题目描述
暑假又到了,小A同学要进行 N 天的旅行,旅行社收费方案是按天收,即第 i 天的费用为
A
i
A_i
Ai ,当然假期旅行社搞活动推出了优惠券,你买了优惠券可以优惠 D 天(不一定连续)的费用,优惠后的价格为 P。如果剩余 2 天,优惠券的作用是 3 天,那么依然可以使用。
小A同学如何做才能在这 N 天旅行中花费最小呢?
输入格式
第一行有 3 个整数 N,D,P。
第二行有 N 个整数,第 i 个为 Ai。
输出格式
1 个整数,如题意。
样例 #1
样例输入 #1
5 2 10
7 1 6 3 6
样例输出 #1
20
样例 #2
样例输入 #2
3 1 10
1 2 3
样例输出 #2
6
样例 #3
样例输入 #3
8 3 1000000000
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
样例输出 #3
3000000000
提示
1 < = N < = 2 ∗ 1 0 5 1<=N<=2*10^5 1<=N<=2∗105
1 < = D < = 2 ∗ 1 0 5 1<=D<=2*10^5 1<=D<=2∗105
1 < = P < = 1 0 9 1<=P<=10^9 1<=P<=109
1 < = A i < = 1 0 9 1<=Ai<=10^9 1<=Ai<=109
样例一解释
使用一张优惠券优惠 1,3 天的费用,总费用为 ( 10 × 1 ) + ( 0 + 1 + 0 + 3 + 6 ) = 20 (10×1)+(0+1+0+3+6)=20 (10×1)+(0+1+0+3+6)=20。
样例二解释
不使用优惠
样例三解释
最低成本是通过购买 3 张优惠券并使用。
1000000000 × 3 = 3000000000。
/*
首先将数组从大到小排序,将其每隔 D 个元素分为一段,如果每一段的所有元素的和小于或等
于
P,就购买正常车票,也就是花费所有元素的和的价钱,否则花费 P 元购买可以使用 D 天的周游
票。
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
using ll= long long;
ll n, d, p, f[N];
int main() {
cin >> n >> d >> p;
for (int i = 1; i <= n; i++) {
cin >> f[i];
}
sort(f + 1, f + 1 + n);
ll ans = 0, c = 0, sum = 0;
for (int i = n; i >= 1; i--) {//从花费多的开始
sum += f[i];
c++;
if (c == d) {//分成多段,每段 d 个
//小于或等于 P,就购买正常车票,也就是花费所有元素的和的价钱,否则花费 P
元购买可以使用 D 天的周游票
ans += min(p, sum);
c = 0;
sum = 0;
}
}
if (c > 0) ans += min(p, sum);//处理 n%d
cout << ans << endl;
return 0;
}