• 【BZOJ】2876: [Noi2012]骑行川藏


    题意

    给出(s_i, k_i, v_i', E),满足(sum_{i=1}^{n} k_i s_i ( v_i - v_i' )^2 le E, v_i > v_i'),最小化$ sum_{i=1}^{n} frac{s_i}{v_i} $

    分析

    首先是贪心,很显然小于等于号要取等号,即问题转化为,满足(g(V) = sum_{i=1}^{n} k_i s_i ( v_i - v_i' )^2 = E),最小化$ f(V) = sum_{i=1}^{n} frac{s_i}{v_i}$。于是拉格朗日乘数大法好。

    题解

    拉格朗日乘数:
    满足(g(X) = c),最大(小)化(f(X)),其中(X)是向量。
    大概就是令(F(X, lambda) = f(X) + lambda (g(X) - c)),得到(|X|+1)个偏导为0的方程,答案就是所有解的其中一个。
    对于本题:

    $$ egin{align} F(V, lambda) & = f(V) + lambda (g(V) - E) \ & = sum_{i=1}^{n} left( frac{s_i}{v_i} + lambda k_i s_i ( v_i - v_i' )^2 ight) - lambda E \ & = sum_{i=1}^{n} left( frac{s_i}{v_i} + lambda k_i s_i v_i^2 + lambda k_i s_i {v'}_i^2 - 2lambda k_i s_i v'_i v_i ight) - lambda E \ end{align} $$

    解出偏导方程,得到:

    $$ 2 lambda k_i v_i^2 (v_i - v'_i) - 1 = 0 $$

    由于(v_i > v_i'),所以对于答案的解来说,(lambda>0)。而且还可以发现(v_i)关于(lambda)单调,然后得到((v_i - v ' _ i))关于(lambda)单调。所以(g(V))关于(lambda)单调,于是我们可以二分一下(lambda)。得到了(lambda),求(v_i)也可以二分,或者牛顿迭代。

    反思

    1、数学太弱。

    #include <bits/stdc++.h>
    using namespace std;
    typedef double lf;
    const lf oo=1e9, eps=1e-12;
    const int N=10005;
    lf s[N], k[N], vv[N], v[N];
    int n;
    inline lf sqr(lf a) {
    	return a*a;
    }
    lf got(lf lambda) {
    	lf e=0;
    	for(int i=1; i<=n; ++i) {
    		lf l=0, r=oo, go=1/(lambda*k[i]*2);
    		while(r-l>=eps) {
    			lf mid=(l+r)/2;
    			if(sqr(mid)*(mid-vv[i])<=go) {
    				l=mid;
    			}
    			else {
    				r=mid;
    			}
    		}
    		v[i]=(l+r)/2;
    		e+=k[i]*s[i]*sqr(v[i]-vv[i]);
    	}
    	return e;
    }
    int main() {
    	lf E, l=0, r=oo;
    	scanf("%d%lf", &n, &E);
    	for(int i=1; i<=n; ++i) {
    		scanf("%lf%lf%lf", &s[i], &k[i], &vv[i]);
    	}
    	while(r-l>=eps) {
    		lf mid=(l+r)/2;
    		if(got(mid)<=E) {
    			r=mid;
    		}
    		else {
    			l=mid;
    		}
    	}
    	got((l+r)/2);
    	lf ans=0;
    	for(int i=1; i<=n; ++i) {
    		ans+=s[i]/v[i];
    	}
    	printf("%.9f
    ", ans);
    	return 0;
    }
  • 相关阅读:
    【Java集合】试读LinkedList源码
    【Java集合】试读ArrayList源码
    类加载器ClassLoader的理解
    Spring中Bean的不同配置方式
    Spring中Bean的生命周期
    关于反射的一点理解
    Vector与ArrayList 的理解
    java多态的实现原理(JVM调用过程)(综合多篇文章,参考见文末)
    并发编程的模型分类(转载于https://link.zhihu.com/?target=http%3A//www.54tianzhisheng.cn/2018/02/28/Java-Memory-Model/)强烈推荐!
    Thread线程类
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4985772.html
Copyright © 2020-2023  润新知