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;
}