B3989 [语言月赛 202406] 优惠券 题解

贪心的证明我没做,只是简单的想了一下如果能尽可能的积累优惠劵就可以拿到更大的优惠的想法,然后简单模拟了两种做法。

第一种,有就用

原价12334
支付12-133-1411

第二种,留给贵的用

原价12334
支付12334-1-1-1-19

嗯,然后代码实现
定义i和j分别表示当前最便宜奶茶和最贵奶茶for (i = 1, j = n; i < j; i++)
最便宜的奶茶当然要付全款,然后把优惠累计在j上
cnt += a[i];a[j]–;
那么如果最贵的奶茶被变成0了,就可以把优惠用在第二便宜的奶茶上;
if (a[j] == 0) j–;
因为我的条件是i<j,这样的话退出一定是i>=j了,其实这里还有两种情况,就是最贵的还没有被优惠完,和正好优惠完
最贵的还没有被优惠完:1 1 5,这时候i=j=3,所以a[j]的钱还是需要支付cnt+=a[j]
正好优惠完:1 1 1 ,这时候i=j=2,但是第2杯还是要花钱的cnt+=a[j]
正好优惠完:1 1 1 1,这时候i=3,j=2,在这时候a[j]里的变量就没有什么用了
所以我想到了一个更妙的做法,把用原价买完奶茶后的值改为0,这样就不会出问题了

#include <iostream>
#include <algorithm>

using namespace std;
const int N = 1e3 + 5;
int n, i, j, cnt;
int a[N];
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for (i = 1; i <= n; i++)cin >> a[i];
	for (i = 1, j = n ; i < j; i++) {
		cnt += a[i]; //原价买了最便宜的奶茶
		a[i] = 0;//防止重复计算
		a[j]--;//优惠卷给了最贵的奶茶
		if (a[j] == 0) j--;
	}
	cnt += a[j];
	cout << cnt;
	return 0;
}

比题解区的代码快请添加图片描述

以上仅我个人观点,欢迎各位大佬指正

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值