贪心 Codeforces Round #712 (Div. 2) E题

本文解析了一道关于路径规划问题的算法竞赛题目,涉及从一个城市出发,经所有城市返回起点的最小成本计算。通过贪心策略和排序,作者逐步解释了如何利用节点的成本和距离属性来构造解决方案。关键步骤包括排序城市按ai递减,计算ci之和,以及处理回程最小费用。

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

https://codeforces.com/contest/1504/problem/E

题意:
有n个城市下标1<=i<=n,每个城市有ai和ci,
从城市i到城市j要花费max(aj-ai,ci)。
求从一个城市出发经过所有城市最后回到起点的最小花费

尝试解释:
假设没有回到起点这个要求,
仅仅只是要求从一个城市出发,然后经过所有城市的花费最小,
我们可以按照ai从大到小排序,从a大的城市到a小的城市,
这样从城市i到城市j,a[j] < a[i]
所以每次的花费 = max(a[ j ] - a[ i ] , c[ i ] ) = c[ i ] 达到最小

但是因为要回到起点,所以这样排序之后还要算上一段,
max (amax - amin , c)
这里算的是 a最小的城市 直达 a最大的城市的花费

从a大的城市到a小的城市的花费不会变,都是ci。
所以我们要想方法使a最小的城市 到达 a最大城市的花费最小,


由 max(aj-ai,ci) => 经过所有城市的花费至少为 所有ci之和
可以先让 res = 所有ci之和
max(aj-ai,ci) => 如果aj - ai > ci , 取max,即aj - ai
因为已经先算上了ci
所以当aj - ai > ci 时(aj - ai - ci) + ci 与 取max等同
即 在 aj > ai + ci 时 , res += aj - (ai + ci)就好

在这里插入图片描述
好吧,解释不太来
也可能是我似懂非懂,贪心好难

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10;

int t,n,m;
struct node{
    ll a,c;
    bool operator<(const node &t)const{
        if(a == t.a) return c > t.c;
        return a < t.a;
    }
}e[N];

int main(){
    scanf("%d",&n);
    ll res = 0;
    for(int i=1;i<=n;i++){
        scanf("%lld %lld",&e[i].a,&e[i].c);
        res += e[i].c;
    }
    sort(e+1,e+1+n);
    ll maxs = e[1].a + e[1].c;
    for(int i=1;i<=n;i++){
        if(maxs < e[i].a){
            res += e[i].a - maxs;
        }
        maxs = max(maxs,e[i].a+e[i].c);
    }
    printf("%lld\n", res);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值