洛谷题单【算法1-5】贪心——P3817 小A的糖果

77 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

P3817 小A的糖果

题目描述

小 A 有 nn 个糖果盒,第 ii 个盒中有 aia_i 颗糖果。

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

输入格式

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

第二行有 nn 个用空格隔开的整数,第 ii 个整数代表第 ii 盒糖的糖果个数 aia_i

输出格式

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

样例 #1

样例输入 #1

3 3
2 2 2

样例输出 #1

1

样例 #2

样例输入 #2

6 1
1 6 1 2 0 4

样例输出 #2

11

样例 #3

样例输入 #3

5 9
3 1 4 1 5

样例输出 #3

0

提示

样例输入输出 1 解释

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


样例输入输出 2 解释

第 2 盒糖吃掉 66 颗,第 4 盒吃掉 22 颗,第 6 盒吃掉 33 颗。


数据规模与约定

  • 对于 30%30\% 的数据,保证 n20n \leq 20ai,x100a_i, x \leq 100
  • 对于 70%70\% 的数据,保证 n103n \leq 10^3ai,x105a_i, x \leq 10^5
  • 对于 100%100\% 的数据,保证 2n1052 \leq n \leq 10^50ai,x1090 \leq a_i, x \leq 10^9

思路

两个盒子的和数超过了限制

那么这里如果从前往后减,则优先减去后面盒子的数,如果后面盒子不够减,再减前面盒子的数

因为这样可以尽可能的让减的盒子处于中央位置,减去的糖果数可以影响到前后两个盒子

代码

// P3817 小A的糖果
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(int argc, char const *argv[])
{
    ll ret = 0;
    int n;
    int x;
    vector<int> a;
    cin >> n >> x;
    //读取数据
    for(int i=0; i<n; i++){
        int temp;
        cin >> temp;
        a.push_back(temp);
    }
    for(int i=1; i<n; i++){
        if(a[i]+a[i-1] > x){
            int dec = a[i] + a[i-1] - x;
            //两个盒子的糖果数和超出x
            if(a[i] >= dec){
                a[i] -= dec;
                ret += dec;
            } else if(a[i] < dec){
                ret += dec;
                a[i-1] -= dec - a[i];
                a[i] = 0;
            }    
        }
    }
    cout << ret;
    return 0;
}