• BZOJ1492: [NOI2007]货币兑换Cash


    CDQ的论文讲的非常清楚了

    事实上这一道题写成斜率优化的形式之后我们会发现一个非常严重的问题  斜率不是单调的

    然后能用斜率优化么?能够。

    。用CDQ将前一半的决策点处理一边 后一半就能线性更新了

    然后总的复杂度是CDQ分治的复杂度

    %%%CDQ

    代码的话是直接copy的    昨天打代码手打残了  不想打了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define eps 1e-9
    #define inf 0x7fffffff
    #define ll long long
    using namespace std;
    int n,top,stack[200005];
    double f[200005];
    struct point{double x,y,a,b,k,rate;int id,w;}p[100005],t[100005];
    double getk(int a,int b)
    {
    	if(!b)return -1e20;
    	if(fabs(p[a].x-p[b].x)<eps)return 1e20;
    	return (p[b].y-p[a].y)/(p[b].x-p[a].x);
    }
    inline bool operator<(point a,point b){return a.k>b.k;}
    void solve(int l,int r)
    {
    	if(l==r)
    	{
    		f[l]=max(f[l],f[l-1]);
    		p[l].y=f[l]/(p[l].a*p[l].rate+p[l].b);
    		p[l].x=p[l].rate*p[l].y;
    		return;
    	}
    	int l1,l2,mid=(l+r)>>1,j=1;
    	l1=l;l2=mid+1;
    	for(int i=l;i<=r;i++)
    	    if(p[i].id<=mid)t[l1++]=p[i];
    	    else t[l2++]=p[i];
    	    for(int i=l;i<=r;i++)p[i]=t[i];
    	solve(l,mid);
    	top=0;
    	for(int i=l;i<=mid;i++)
    	{
    		while(top>1&&getk(stack[top-1],stack[top])<getk(stack[top-1],i)+eps)
    		    top--;
    		stack[++top]=i;
        }
        stack[++top]=0;
        for(int i=mid+1;i<=r;i++)
        {
        	while(j<top&&getk(stack[j],stack[j+1])+eps>p[i].k)j++;
            f[p[i].id]=max(f[p[i].id],p[stack[j]].x*p[i].a+p[stack[j]].y*p[i].b);
    	}
    	solve(mid+1,r);
    	l1=l;l2=mid+1;
    	for(int i=l;i<=r;i++)
    	   if(((p[l1].x<p[l2].x||(fabs(p[l1].x-p[l2].x)<eps&&p[l1].y<p[l2].y))||l2>r)&&l1<=mid)t[i]=p[l1++];
    	   else t[i]=p[l2++];
        for(int i=l;i<=r;i++)p[i]=t[i];
    }
    int main()
    {
    
    	scanf("%d%lf",&n,&f[0]);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lf%lf%lf",&p[i].a,&p[i].b,&p[i].rate);
    		p[i].k=-p[i].a/p[i].b;p[i].id=i;
    	}
    	sort(p+1,p+n+1);
    	solve(1,n);
    	printf("%.3lf",f[n]);
    	return 0;
    }


  • 相关阅读:
    河北金力集团公文流转系统
    输出《Harry Potter and the Sorcerer's Stone》英文i的字母数量并排序
    四则运算自动出题系统
    输出《Harry Potter and the Sorcerer's Stone》文本中的前N个最长用的英文单词及其数量
    《程序员的修炼之道从小工到专家》第二章阅读有感
    异常处理动手动脑
    poj 1860
    poj 2182
    poj 2253
    poj 2001
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7140944.html
Copyright © 2020-2023  润新知