cf893 D. Credit Card(贪心)

题意:

初始有0元,每天晚上余额加上 \(a_i\)\(a_i=0\) 表示查询余额。每天早上可以充钱。要求每次查询时余额不为负,且任何时候余额不超过 \(d\)。问最少要充几次钱。

思路:

易知肯定是在 \(a_i=0\) 的白天充钱。

首先正序扫一遍看有没有可行方案:如果某天要查询且余额为负就充到余额为0。任何时候出现越界就输出-1

然后再正序扫一遍,贪心找最优解:如果某天要查询且余额为负就直接充满(d)。任何时候若出现越界(\(s>d\)),余额只需减少 \(s-d\),相当于上一次充钱少充 \(s-d\)

const int N = 1e5 + 5;
int n, d, a[N];

signed main()
{
    scanf("%d%d", &n, &d);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);

    for(int i = 1, s = 0; i <= n; i++)
    {
        s += a[i];
        if(!a[i] && s < 0) s = 0;
        if(s > d) return puts("-1"), 0;
    }

    int ans = 0;
    for(int i = 1, s = 0; i <= n; i++)
    {
        s += a[i];
        if(!a[i] && s < 0) s = d, ans++;
        if(s > d) s = d;
    }

    printf("%d", ans);
}

posted @ 2022-02-10 17:09  Bellala  阅读(108)  评论(0)    收藏  举报