CSP-J2023 T2公路 blog

#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
ll n,d;
ll t=0,oil=0;//oil:理想油量
//ll sjoil=0;
float sjoil=0.0f;//多余的油量
int main(){
cin>>n>>d;
ll s[n];//里程(前缀和)
ll a[n];//每个站点的价值
s[0]=0;
for(int i=1;i<n;i++){//前缀和
    cin>>s[i];
    s[i]+=s[i-1];
}
for(int j=0;j<n;j++){
    cin>>a[j];
}
for(int i=0,j=1;j<n;j++){
    if(a[i]>=a[j]||j==n-1){
        oil=(s[j]-s[i]+d-1)/d;//(dis/d)向上取整=加的油数量
        sjoil+=float(oil)-float(s[j]-s[i])/float(d);
        oil-=int(sjoil);//减去多加的油,得出实际加的油,sjoil>=1时oil会减去1
        if(sjoil>=1)sjoil--;//剩余油量被消耗完了后要减去1
        t+=a[i]*oil;
        i=j;
    }
}
cout<<t;//输出总价
return 0;
}

 贪心,大体思路是:

设所在油站的编号为i,那么到达终点的平均油价就是a[i](如果中途没有可以加油的地方的话),因为所有的路程消耗的油全部来自站点i。

那么好,中途有多个加油站的时候,可以在i加足量油,使车刚好能到达下一个加油点,设编号为j,此时平均油价设为a1=路程/d(每升油的能走的距离)。因为到达终点时,总油量=总平均油价*路程,路程为常数不变,因此我们要让总平均油价最小,总油价最小。

总平均油价(括号里a的数量取决于实际,如果不懂,就先看完下面的)=(a1+a2+……+an)/n,因此找到a[j]<=a[i](a[n]具体解释看注释)的时候,可以让车在j加油,这样,我们就不需要花费相对较贵的油跑远距离,只要用贵一点的油跑到便宜的地方加便宜一点的,再用便宜的油跑到更便宜的地方……这样,每一段的平均油价(a1,a2,……an)就会最小,总平均油价就会最小,总油价最小。

另外,由于只能加整数升油,因此为了能跑到便宜的地方,必须要向上取整(向上取整a/b= int((a+b-1)/b) )这样就会有剩余的油,那下次,因为剩余油量(sjoil,使用浮点型存取)就可以少加一些,具体操作看代码,记得在消耗完剩余油量之后减去就可以了。

(End)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值