问题描述
题目描述
小A有n个糖果盒,第i个盒中有a_i颗糖果。
小A每次可以从其中一盒糖果中吃掉一颗,他想知道,要让任意两个相邻的盒子中糖的个数之和都不大于x,至少得吃掉几颗糖。
输入格式
输入的第一行是两个用空格隔开的整数,代表糖果盒的个数n和给定的参数x。
第二行有n个用空格隔开的整数,第i个整数代表第i盒糖的糖果个数a_i。
输出格式
输出一行一个整数,代表最少要吃掉的糖果的数量。
输入输出样例
输入 #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颗,第4盒吃掉2颗,第 6 盒吃掉3颗。
数据规模与约定
对于30%的数据,保证n<=20,a_i,x<=100。
对于70%的数据,保证n<=10^3, a_i,x<=10^5。
对于100%的数据,保证2<=n<=10^5, 0<=a_i,x<=10^9。
问题分析
这是一道较为简单的贪心问题,因为要保证任意两个相邻的盒子中糖的个数之和都不大于x,所以必须要将两个相邻的糖的个数相加并和x进行比较,如果相邻的糖的个数相加大于x则必须吃掉多余的部分,问题的重点在于吃哪一份糖果,很明显,只有后面一份糖果的数量会影响到之后计算相邻糖果数量,所以后面一份糖果的数目越少,之后的相邻糖果数会变得越少,所以我们选择多余的部分吃的全是后面一部分的糖果,这样我们就可以得到最优解。
代码实现
#include <iostream>
using namespace std;
int n, x;
long long ans; //注意答案范围可能超出int型的大小
int a[100005];
int main()
{
cin >> n >> x;
for (int i = 0; n > i; i++)
cin >> a[i];
for (int i = 0; n > i; i++)
{
if (a[i] + a[i + 1] > x)
{
ans += a[i] + a[i + 1] - x;
a[i+1] -= a[i] + a[i + 1] - x; 吃后面一堆糖果即a[i+1]
}
}
cout << ans;
return 0;
}
运行结果
总结
贪心算法的特点是只考虑眼前的利益最大化,虽然有可能会出错,但幸运的是大多数情况下还是可行的。