Educational Codeforces Round 106 (Rated for Div. 2) C. Minimum Grid Path

题目链接

  • 思路:

只能往上和右走(直角坐标系y轴关于x轴对称下来,然后x和y调换下位置),所以总共走的路长只有2*n

由于每个a[i]代表的是在下一次转向前每走一步的花费,所以可以考虑贪心

只要找到最小的每步代价,将前面的都置为一步,剩下的用最小代价走完,所得的总代价即为答案

枚举每一个a[i],对于前面的代价和i个单次步长,直接使用前缀和即可,然后循环中每次分别维护x轴和y轴上的最小值计算即可

  • 代码:

#include <bits/stdc++.h>
#define ll long long

using namespace std;

typedef pair<ll, ll> PII;

const int N = 1e5 + 10, mod = 998244353;

int n;
ll a[N], sum[N];

void solve()
{
    cin >> n;
    for (int i = 1; i <= n; ++ i)
    {
        cin >> a[i];
        sum[i] = sum[i - 1] + a[i];
    }

    ll ans = a[1] * n + a[2] * n;
    ll tempj = a[1], tempo = a[2];
    for (int i = 3; i <= n; i ++)
    {
        if(i % 2) tempj = min(tempj, a[i]);
        else tempo = min(tempo, a[i]);
        ll re = 2 * n - i;
        ll t1 = re / 2, t2 = re - t1; //由于tempj是第一步的,所以奇数时它要比另一方向上多走一次/步,所以直接除即可
        ans = min(ans, sum[i] + t1 * tempj + t2 * tempo);
    }
    cout << ans << endl;
}

int main()
{
    ios::sync_with_stdio(0);
    int T;
    cin >> T;
    while(T --)
    {
        solve();
    }
    return 0;
}

  

上一篇:%%的一个应用


下一篇:pg中join,left join的使用,将条件放到on和where后面的区别问题