CSP-J2023 T2公路 blog

#include
#include
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>s[i];
    s[i]+=s[i-1];
}
for(int j=0;j>a[j];
}
for(int i=0,j=1;j=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<

 贪心,大体思路是:

设所在油站的编号为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)

你可能感兴趣的:(算法,c++,数据结构)