题目链接
-
思路:
只能往上和右走(直角坐标系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; }