zoukankan      html  css  js  c++  java
  • bzoj1492 [NOI2007]货币兑换Cash【cdq分治】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1492

    推荐博客:http://www.cnblogs.com/zig-zag/archive/2013/04/24/3039418.html

    保存cdq分治模版代码。

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    
    const int maxn = 100005;
    const double eps = 1e-9, inf = 1e300;
    
    int n, s;
    double a[maxn], b[maxn], rate[maxn], f[maxn];
    
    struct point {
    	double x, y;
    	int id;
    	bool operator<(const point & rhs) const {
    		if (fabs(x - rhs.x) < eps) {
    			return y > rhs.y + eps;
    		}
    		return x + eps < rhs.x;
    	}
    } stk[maxn], p[maxn], np[maxn];
    struct query {
    	double k;
    	int id;
    } q[maxn], tq[maxn];
    
    bool cmp(const query & aa, const query & ss) {
    	return aa.k > ss.k;
    }
    inline double getk(const point & aa, const point & ss) {
    	if (fabs(aa.x - ss.x) < eps) {
    		return -inf;
    	}
    	return (ss.y - aa.y) / (ss.x - aa.x);
    }
    
    void slove(int left, int right) {
    	if (left == right) {
    		f[left] = std::max(f[left], f[left - 1]);
    		p[left].y = f[left] / (a[left] * rate[left] + b[left]);
    		p[left].x = p[left].y * rate[left];
    		return;
    	}
    	
    	int mid = (left + right) >> 1, idx1 = left, idx2 = mid + 1;
    	for (int i = left; i <= right; ++i) {
    		if (q[i].id <= mid) {
    			tq[idx1++] = q[i];
    		}
    		else {
    			tq[idx2++] = q[i];
    		}
    	}
    	memcpy(q + left, tq + left, sizeof(query) * (right - left + 1));
    	
    	slove(left, mid);
    	
    	int top = 0;
    	stk[top++] = p[left];
    	for (int i = left + 1; i <= mid; ++i) {
    		while (top > 1 && getk(p[i], stk[top - 1]) > getk(stk[top - 1], stk[top - 2]) + eps) {
    			--top;
    		}
    		stk[top++] = p[i];
    	}
    	
    	int j = 0;
    	for (int i = mid + 1; i <= right; ++i) {
    		while (j < top - 1 && getk(stk[j], stk[j + 1]) > q[i].k + eps) {
    			++j;
    		}
    		f[q[i].id] = std::max(f[q[i].id], stk[j].x * a[q[i].id] + stk[j].y * b[q[i].id]);
    	}
    	
    	slove(mid + 1, right);
    	
    	idx1 = left, idx2 = mid + 1;
    	for (int i = left; i <= right; ++i) {
    		if (idx1 <= mid && (p[idx1] < p[idx2] || idx2 > right)) {
    			np[i] = p[idx1++];
    		}
    		else {
    			np[i] = p[idx2++];
    		}
    	}
    	memcpy(p + left, np + left, sizeof(point) * (right - left + 1));
    }
    
    int main(void) {
    	scanf("%d%d", &n, &s);
    	f[0] = (double)s;
    	for (int i = 1; i <= n; ++i) {
    		scanf("%lf%lf%lf", a + i, b + i, rate + i);
    		q[i] = (query){-a[i] / b[i], i};
    	}
    	
    	std::sort(q + 1, q + n + 1, cmp);
    	slove(1, n);
    	printf("%.3lf
    ", f[n]);
    	return 0;
    }
    

      

  • 相关阅读:
    使用SignalR实现即时通讯功能
    SignalR入门篇
    Mongodb关闭开源许可感想
    RaspberryPi学习教程系列4(串口通信篇)
    RaspberryPi学习教程系列3(编程实验篇-双色LED实验)
    RaspberryPi学习教程系列1(系统安装篇)
    RaspberryPi学习教程系列2(编程前准备篇)
    关于Entity Framework,园里有非常多误人子弟的`
    Java多线程1:使用多线程的几种方式以及对比
    Django编写RESTful API(六):ViewSets和Routers
  • 原文地址:https://www.cnblogs.com/ciao-sora/p/6700991.html
Copyright © 2011-2022 走看看