【题解】【洛谷P3817】【贪心】——小A的糖果

小A的糖果

通往洛谷的传送门

题目描述

小 A 有 n n n 个糖果盒,第 i i i 个盒中有 a i a_i ai 颗糖果。

小 A 每次可以从其中一盒糖果中吃掉一颗,他想知道,要让任意两个相邻的盒子中糖的个数之和都不大于 x x x,至少得吃掉几颗糖。

输入格式

输入的第一行是两个用空格隔开的整数,代表糖果盒的个数 n n n 和给定的参数 x x x

第二行有 n n n 个用空格隔开的整数,第 i i i 个整数代表第 i i i 盒糖的糖果个数 a i a_i ai

输出格式

输出一行一个整数,代表最少要吃掉的糖果的数量。

输入输出样例

输入 #1

3 3
2 2 2

输出 #1

1

输入 #2

6 1
1 6 1 2 0 4

输出 #2

11

输入 #3

5 9
3 1 4 1 5

输出 #3

0

提示

样例输入输出 1 解释

吃掉第 2 盒中的一个糖果即可。


样例输入输出 2 解释

第 2 盒糖吃掉 6 6 6 颗,第 4 盒吃掉 2 2 2 颗,第 6 盒吃掉 3 3 3 颗。


数据规模与约定
  • 对于 30 % 30\% 30% 的数据,保证 n ≤ 20 n \leq 20 n20 a i , x ≤ 100 a_i, x \leq 100 ai,x100
  • 对于 70 % 70\% 70% 的数据,保证 n ≤ 1 0 3 n \leq 10^3 n103 a i , x ≤ 1 0 5 a_i, x \leq 10^5 ai,x105
  • 对于 100 % 100\% 100% 的数据,保证 2 ≤ n ≤ 1 0 5 2 \leq n \leq 10^5 2n105 0 ≤ a i , x ≤ 1 0 9 0 \leq a_i, x \leq 10^9 0ai,x109

1.思路解析

    大体思路:循环判断每一组相邻的糖果盒( a [ i ] a[i] a[i] a [ i + 1 ] a[i+1] a[i+1])。如果它们的糖果数量的总和超过了上限。就一直吃,直到没有超出上限为止。问题是:吃哪一个盒子之中的糖果好呢?

    贪心策略:遍历所有(每两个相邻的糖果盒为一组)糖果盒,如果超过上限就尽量挑右边的吃,以便影响到后面的糖果盒。

    证明(反证法):假设每一次挑左边的吃可以达成最优解,直接看看这一组样例:

3 3
2 2 2

    用我们猜想的贪心策略,得到的答案是:

1 1 2
2

    为什么会出现这种情况呢?我们的预期是:每一组超出上限的糖果盒吃完后都刚好达到上限。但是这样的贪心策略就导致了已经处理完的组有可能还会受影响。无法达成最优解。假设错误,贪心策略正确。
在这里插入图片描述
    如上图所示,当我们改变a[2]时,a[1]a[3]都会受到影响。因此,如果超过上限就尽量挑右边的吃可以达成最优解。

2.AC代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long n,x,a[100010],ans=0;
    cin>>n>>x;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<n;i++)
        if(a[i]+a[i+1]>=x)//如果超出上限 
        {
        	int num=a[i]+a[i+1]-x;//计算超出的数量 
        	ans+=num;
        	if(a[i+1]<num)//如果右边的不够减,左边的也要减 
			    a[i]-=a[i+1]-num,a[i+1]=0;
        	else a[i+1]-=num;//否则就直接减右边的 
		}
	cout<<ans;
	return 0;
}

喜欢就订阅此专辑吧!

【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。

欢迎扫码关注蓝胖子编程教育
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝胖子教编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值