2017.9.26 货币兑换 失败总结

来源:互联网 发布:知天气福建版 数值预报 编辑:程序博客网 时间:2024/05/04 02:56

这个题首先要注意到提示:全买全卖,,不然很容易误入歧途

然后可以根据确定性n^2 dp,,由于它是全买全卖,所以枚举上一个买入的点在哪里,算全卖出的价值取max

     如果这个点不卖,则它一定有钱,所以继承前面最大的钱取max,

    然后考虑在这个点卖,由于a:b是定值,钱和数量是直接相关的  所以只记录一个b的数量即可


f【i】=max(f【i-1】,A【j】*fa【i】+B【j】*fb【i】)

用斜率优化的方式化式子:

-A【j】=fa【i】/ fb【i】 *B【j】*rate【j】  -  f【i】/fb【i】

    y       =          k                          x                 +             b

注意正负号,第一次式子写错了调了2h、


然后就需要x、k的单调性,就可以用cdq分治

对左区间操作     对整体操作      对右区间操作    ←顺序非常重要

由于y是负值   ,b是负值   ,  f【i】∝  -b

所以要让-b最大,  b就要最小

由于x、k单增,所以最优点一定在下凸包上

所以左区间按x排序  右区间按k排序,转移即可

注意排完之后要按时间顺序还原


复杂度  o(nlog^2n)


码(常数巨大,超时卡过):

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;double ans;int n,m,i,j,k,q[100005],s;struct tian{double fa,fb,id,R,k,B,f;}d[100005];bool cmp1(tian a,tian b){return a.id<b.id;}bool cmp2(tian a,tian b){return a.B*a.R<b.B*b.R;}bool cmp3(tian a,tian b){return a.fa/a.fb<b.fa/b.fb;}double xl(int a,int b){return (-d[a].B+d[b].B)/(d[a].B*d[a].R-d[b].B*d[b].R);}void cdq(int l,int r){if(l==r){if(d[l].f<d[l-1].f){d[l].f=d[l-1].f;d[l].B=d[l].f/(d[l].R*d[l].fa+d[l].fb);}return;}int mid=(l+r)>>1;cdq(l,mid);for(i=l;i<=mid;i++)if(d[i].f<d[i-1].f){d[i].f=d[i-1].f;d[i].B=d[i].f/(d[i].R*d[i].fa+d[i].fb);}sort(d+l,d+mid+1,cmp2);sort(d+mid+1,d+r+1,cmp3);int z1=1,z2=0;for(i=l;i<=mid;i++){while(z1<z2&&xl(q[z2-1],i)>=xl(q[z2],i))z2--;q[++z2]=i;}for(i=mid+1;i<=r;i++){while(z1<z2&&d[q[z1]].B*d[i].fb+d[q[z1]].B*d[q[z1]].R*d[i].fa<=d[q[z1+1]].B*d[i].fb+d[q[z1+1]].B*d[q[z1+1]].R*d[i].fa)z1++;if(d[i].f<d[q[z1]].B*d[i].fb+d[q[z1]].B*d[q[z1]].R*d[i].fa){d[i].f=d[q[z1]].B*d[i].fb+d[q[z1]].B*d[q[z1]].R*d[i].fa;d[i].B=d[i].f/(d[i].R*d[i].fa+d[i].fb);}}sort(d+l,d+mid+1,cmp1);sort(d+mid+1,d+r+1,cmp1);//消除影响,按实际安排cdq(mid+1,r);}int main(){scanf("%d%d",&n,&s);d[0].f=s;for(i=1;i<=n;i++){scanf("%lf%lf%lf",&d[i].fa,&d[i].fb,&d[i].R);d[i].id=i;    d[i].k=d[i].fa/d[i].fb;}cdq(1,n);ans=d[i].f;for(i=2;i<=n;i++){ans=max(ans,d[i].f);}printf("%.3lf",ans);}


       

     


原创粉丝点击