【思维+前缀和】Educational Codeforces Round 106 (Rated for Div. 2) C. Minimum Grid Path

本文分享了C.MinimumGridPath题目的解题思路与参考代码。该问题要求找到从坐标(0,0)到(n,n)的路径中最小花费,路径只能向右或向上移动。文章介绍了使用前缀和优化的思维解决此问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思维+前缀和

C. Minimum Grid Path

有生之年第一次做出C,WA了7发qwq,激动的要哭惹

题目大意

( 0 , 0 ) (0,0) (0,0) ( n , n ) (n,n) (n,n),可以向右或向上走,每次的线段有花费,求最小花费。

解题思路

对于向右的线段,最优方法一定是花费最少的线段走最长,其他的都走最短(即走 1 1 1)。处理的时候就记录当前最小的 c i c_i ci,用前缀和优化。

对于向上的同理。

具体解题的时候遍历所有的 c i c_i ci,如 c 1 , c 2 , c 3 c_1,c_2,c_3 c1,c2,c3,那么看作 c 1 , c 3 c_1,c_3 c1,c3 是向右, c 2 c_2 c2 是向左,分别处理即可。

注意事项

1.不开 l o n g   l o n g long \ long long long 见祖宗~

参考代码

#include<stdio.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
#include<climits>
#include<cmath>
#include<algorithm>
#include<queue>
#include<deque>
#include<map>
#include<unordered_map>
#include<set>
#include<stack>
//#define LOCAL  //提交时一定注释
#define VI vector<int>
#define eps 1e-8
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
using namespace std;
typedef long long LL;
typedef double db;
const int inf = 0x3f3f3f3f;
const LL INF = 1e18;
const int N = 1e5 + 10;

inline int readint() {int x; scanf("%d", &x); return x;}

int c[N];

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
//   freopen("output.txt", "w", stdout);
#endif
    int t = readint();
    while (t--) {
        int n = readint();
        for(int i = 0; i < n; ++i) {
            c[i] = readint();
        }
        LL a = INF;  //记录答案
        LL sum1 = c[0], sum2 = c[1];  //分别为两个部分的前缀和
        int min1 = c[0], min2 = c[1];  //分别为两个部分的最小值
        LL a1 = 1LL * min1 * n, a2 = 1LL * min2 * n;  //两个部分的答案
        a = a1 + a2;
//        cout << "a1:" << a1 << " " << "a2:" << a2 << endl;
        for(int i = 2; i < n; ++i) {
            if (!(i & 1)) {  //分别处理即可
                sum1 += 1LL * c[i];
                if (c[i] < min1) {
                    min1 = c[i];  //更新最小值
                }
                a1 = 1LL * (sum1 - min1) + 1LL * min1 * (n - (i / 2));  //更新此时这部分的答案
            }
            else {
                sum2 += 1LL * c[i];
                if (c[i] < min2) {
                    min2 = c[i];
                }
                a2 = 1LL * (sum2 - min2) + 1LL * min2 * (n - (i / 2));
            }
            a = min(a, a1 + a2);  //更新最终的答案
        }
        printf("%lld\n", a);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值