牛客竞赛小白月赛39补题

H

在这里插入图片描述
AC代码:

#include <iostream>
#include <algorithm>
using namespace std;

using ll = long long;
const int N = 1e6 + 5;

ll a[N];
ll dp1[N], dpl[N]; //dp1[i]维护前i只需要砍的次数,dpl[i]代表以第i只为最左边挥刀次数。
ll dp2[N], dpr[N]; //dp2[i]维护后i只需要砍的次数,dpr[i]代表以第i只为最右边挥刀次数。

int main()
{
    ios::sync_with_stdio(false), cin.tie(0);
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i];

    dp1[1] = a[1];
    dpl[1] = a[1];
    ll k;
    //cout << dp1[1] << ' ';
    for (int i = 2; i <= n; i++)
    {
        k = a[i] - (dpl[i - 1] + dpl[i - 2]);
        dp1[i] = k <= 0 ? dp1[i - 1] : dp1[i - 1] + k;
        dpl[i] = k <= 0 ? 0 : k;
        //cout << dp1[i] << ' ';
    }
    //cout << '\n';

    dp2[n] = a[n];
    dpr[n] = a[n];

    //cout << dp2[n] << ' ';
    for (int i = n - 1; i >= 1; i--)
    {
        k = a[i] - (dpr[i + 1] + dpr[i + 2]);
        dp2[i] = k <= 0 ? dp2[i + 1] : dp2[i + 1] + k;
        dpr[i] = k <= 0 ? 0 : k;

        //cout << dp2[i] << ' ';
    }
    // cout << '\n';

    ll ans = 1e18;
    for (int i = 1; i <= n - 1; i++)
    {
        ans = min(ans, dp1[i - 1] + dp2[i + 2]);
    }
    cout << ans << '\n';
}

贪心题,比赛中想到了贪心没有想到贪心的方式。一直执着于少挥空刀,导致走偏了。
实际上可以换个方向考虑,从第一只开始考虑,由于最后其血量一定为0,故考虑砍他的方式,易知将1,2,3一起砍对结果的贡献最大,所以由第一只一直向后砍,每次砍最左边的直到其血量为0,既可以得到最优解(从最右边到最左边一样),考虑两个dp维护来降低时间复杂度即可。

C

在这里插入图片描述
AC代码:

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 3e6 + 5;

int a[N], b[N];

int main()
{

    ios::sync_with_stdio(false), cin.tie(0);
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i] >> b[i];
    int A = 0;
    int B = 0;
    long long ans = 0;

    int maxx, minn;

    for (int i = 0; i < n; i++)
    {
        maxx = max(a[i], b[i]);
        minn = min(a[i + 1], b[i + 1]);
        if (maxx <= minn)
        {
            ans += minn - maxx + 1;
            if (a[i] == b[i])
                ans--;
        }
    }
    cout << ans << '\n';
    return 0;
}

竞赛最重要的是解决问题的思路,重点是要用什么方式去解决一个问题,当察觉到方式过于复杂时能否及时转换思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值