贪心
2026-08-20 09:19:35
发布于:广东
7阅读
0回复
0点赞
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 1e5+10;
//核心逻辑 a市为0 b市为x 站点为p a为去a市次数 b为去b市次数
//此时总的运输就是 2*(a*p+b*(x-p))
// = 2*(a*p+b*x-b*p)
// = 2*(b*x + (a-b)*p)
// 设w为a-b = 2*(b*x+w*p)
// 观察得知 只有w部分是受到p影响,也就是受到站点影响
// 当w>0时 p越小越好 w<0时 p越大越好 w = 0 不受p的影响
// 现在只需要分别计算b*x 和w*p的部分
// 对所有的车来说 b*x也就是所有车去b次数*x w*p则需要根据11行注释动态分配再全部加起来
struct site//站点结构体
{
ll p;
ll c;
}s[N];
ll n,m,x;
vector<ll>zheng,fu;
int main() {
cin>>n>>m>>x;
for(int i = 1;i<=n;i++)
cin>>s[i].p>>s[i].c;
ll sumb = 0;//记录所有车去的b的次数
for(int i = 1;i<=m;i++)
{
ll a,b;cin>>a>>b;
sumb+=b;
ll w = a-b;
if(w>0)zheng.push_back(w);
else if(w<0)fu.push_back(w);
// =0 没有w*p部分
}
sort(zheng.begin(),zheng.end(),greater<ll>());//w越大 要对应的p越小 这样距离相对最小 所以后面遍历zheng容器是正序 fu容器是逆序
sort(fu.begin(),fu.end());//w越小(已经是负数了) 要对应的p越大 这样距离相对最小 所以后面遍历zheng容器是正序 fu容器是逆序
//此时sumb*x就是上面式子左半部分算出来
//现在算右半部分 w*p的部分
vector<ll>needs(n+1,0);
ll posz = 0;//用于遍历zheng容器
ll sumwp = 0;//记录后半部分 w*p的总和
for(ll i = 1;i<=n&&posz<zheng.size();i++)
{
ll can = min(ll(zheng.size())-posz,s[i].c);//min(能存下所有的车,不能存下所有的车)
needs[i] = can;//记录该站点消耗了多少台车了
for(ll j = 0;j<can;j++)
sumwp+=zheng[posz+j]*s[i].p;//记录每个车的w*p
posz += can;//调整遍历下标
}
ll posf = 0;//用于遍历fu容器
for(ll i = n;i>=1&&posf<fu.size();i--)
{
ll remain = s[i].c - needs[i];//有些站点可能被zheng容器消耗过
ll can = min(ll(fu.size())-posf,remain);//min(能存下所有的车,不能存下所有的车)
for(ll j = 0;j<can;j++)
sumwp+=fu[posf+j]*s[i].p;//记录每个车的w*p
posf += can;//调整遍历下标
}
//2*(b*x+w*p)//提前把所有的车b*x的总和算出来也就是sumb*x 以及所有车的w*p也就是sumwp;
cout<< 2*(sumb*x +sumwp);
return 0;
}
这里空空如也


有帮助,赞一个