蓝桥杯——大石头的搬运工

题目就不在这里记录了,蓝桥杯官网都有,以后想看可以回去找找。

前缀和

本题的主要思想就是利用前缀和,记录对应位置前面所有石头要移动到此处的费用和后面所有石头要移动到此处的费用,对每一个位置进行这样的记录,并对此比较大小。

细节

1、将数组中盛放pair容器,使用方便快捷。

2、起初检测的时候总是所有点都不通过,但是题目给的样例却可以通过。原因是题目样例数据很小,而题目给出的重量w和距离p的大小范围都是1~1e5,所以费用最后算起来绝对会大于1e10,也就大于了int的最大范围2^31-1(一个int是4Byte,也就是32bit),所以要用long long长整型。

#include <bits/stdc++.h>
using namespace std;
using ll = long long; //注意数据大小
using s = pair<int, int>;
const int maxn =  1e5 + 9;

s arr[maxn];
ll pre[maxn], nex[maxn]; //记录前面所有的石头移到此位置的费用,和后面所有石头移到此位置的费用

int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n; cin >> n;
    for (int i = 1; i <= n; i++) {
        int w, p; cin >> w >> p;
        arr[i].first = p;
        arr[i].second = w;
    }

    sort(arr + 1, arr + n + 1);

    ll tw = 0;
    for (int i = 1; i <= n; i++) {
        pre[i] = pre[i - 1] + tw * (arr[i].first - arr[i - 1].first);
        tw += arr[i].second;
    }
    tw = 0; //目前石头总重量
    for (int i = n; i >= 1; i--) {
        nex[i] = nex[i + 1] + tw * (arr[i + 1].first - arr[i].first);
        tw += arr[i].second;
    }

    ll ans = pre[1] + nex[1];
    for (int i = 1; i <= n; i++) {
        ans = min(ans, pre[i] + nex[i]);
      
    }
    cout << ans << endl;
    return 0;
}

ps:一开始真没想到要用前缀和写,但这个思路确实是最好的,希望对前缀和可以越来越熟悉!

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值