• [NOI2007]货币兑换


    [NOI2007]货币兑换

    有n天,第i天有一个属性(a_i,b_i,r_i)表示当天股票a,b的价值分别为(a_i,b_i),且购买的a,b股票数量比值为(a_i/b_i),要求要卖股票要全部卖完,买股票要用完全部的钱,现在初始有s钱,为n天后最大的钱数,(n ≤ 100 000)

    设第j天能够购买股票a,b的数量分别为(x_j,y_j),拥有的钱数为(f_j),不难有

    (x_ja_j+y_jb_j=f_j)

    (frac{x_j}{y_j}=r_j)

    解得

    (x_j=frac{r_jf_j}{r_ja_j+b_j},y_j=frac{f_j}{r_ja_j+b_j})

    因此有方程

    [f_i=_{0leq j<i}x_ja_i+y_jb_i ]

    边界:(f_0=s),其余无限小

    答案:(f_n)

    注意到式子需要优化,因为j,i的关系密切,考虑斜率优化,因此不难得知斜率优化式为

    [-y_j=frac{a_i}{b_i}x_j-frac{f_i}{b_j} ]

    注意到(b_j)为正数,所以截距要尽可能小,但是不存在单调性,于是考虑set维护动态插点,删点,查斜率,时间复杂度(O(nlog^n))

    参考代码:

    #include <iostream>
    #include <cstdio>
    #include <set>
    #define il inline
    #define ri register
    #define db double
    #define Size 100050
    #define intmax 1e66
    using namespace std;bool cmp;
    struct DATA{db x,y;db *k;
    	il bool operator<(const DATA&a)const{
    		if(cmp)return x<a.x;return *k<*a.k;}
    };set<DATA>S;db a[Size],b[Size],r[Size],dp[Size];
    il void insert(int);il db dfs(int);
    template<class free>il free Max(free,free);
    int main(){
    	int n,s;scanf("%d%lf",&n,&dp[1]);
    	for(int i(1);i<=n;++i)scanf("%lf%lf%lf",&a[i],&b[i],&r[i]);
    	insert(1);for(int i(2);i<=n;++i)dp[i]=Max(dfs(i),dp[i-1]),insert(i);
    	printf("%.3lf",dp[n]);
    	return 0;
    }
    template<class free>
    il free Max(free a,free b){
    	return a>b?a:b;
    }
    il void insert(int i){cmp|=true;DATA m;
    	m.x=dp[i]*r[i]/(a[i]*r[i]+b[i]),m.y=-m.x/r[i],
    		m.k=new db(intmax);
    	set<DATA>::iterator M(S.insert(m).first),L(M),R(M);
    	if(L!=S.begin()&&++R!=S.end())
    		if(--L,(L->y-M->y)/(L->x-M->x)>=(R->y-M->y)/(R->x-M->x))
    			return (void)(S.erase(M));L=M,R=L,--R;
    	while(L!=S.begin()){L=R;
    		*L->k=(L->y-M->y)/(L->x-M->x);
    		if(L==S.begin())break;--(R=L);
    		if(*R->k>=*L->k)S.erase(L);
    		else break;}++(R=M);
    	while(R!=S.end()){*M->k=(M->y-R->y)/(M->x-R->x);
    		if(*M->k>=*R->k)L=R,++R,S.erase(L);else break;}
    }
    il db dfs(int i){
    	cmp&=0;DATA t((DATA){0,0,new db(a[i]/b[i])});
    	set<DATA>::iterator c(S.lower_bound(t));return c->x*a[i]-c->y*b[i];
    }
    
    
    
  • 相关阅读:
    maven项目编译漏掉src/main/java下的xml配置文件
    读《架构探险——从零开始写Java Web框架》
    使用generator自动生成Mybatis映射配置文件
    git项目添加.gitigore文件
    git-bash下, 启动sshd
    git-bash.exe参数
    少估了一分, 还算不错
    python常用库
    Linux下python pip手动安装笔记
    python学习笔记
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/10976447.html
Copyright © 2020-2023  润新知