• CodeForces


    【传送门】http://codeforces.com/problemset/problem/813/C

    【题意】给定整数a,b,c,s,求使得  xa yzc值最大的实数 x,y,z , 其中x + y + z <= s. (1 ≤ S ≤ 103  , 0 ≤ a, b, c ≤ 103)

    【题解】设P(x,y,z ) = xa yzc,则P(x,y,z)是递增的,要使 函数值尽可能地大,那么必取 x + y + z = s

    问题转化成:已知限定条件  x + y + z = s, 求P(x,y,z)取得最大值的(x,y,z)

    显然,这是运用拉格朗日乘数法的模板题。

    【拉格朗日乘数法】

    解决的问题模型 : 已知G(x,y,z) = 0

    求F(x,y,z)最值(或者极值,一般情况下拉格朗日乘数法求得的极值点就是最值点)

    设L(x,y,z) = F(x,y,z) + λG(x,y,z)

    将L(x,y,z)分别对x,y,z求偏导,得到3个四元一次方程,加上原来的一个限定条件G(x,y,z) = 0,共得到4个方程,解4个未知数(x,y,z,λ)

    求出极值点(x, y , z)即可。

    最值只可能在边界处或者极值点处取到,一般情况下极值点就是最值点

    【回到本题】令G(x,y,z) = x + y + z - s , F(x,y,z) = alnx + blny + clnz  .用上述方法解出极值点(s*a/(a+b+c) , s*b/(a+b+c), s*c/(a+b+c))这就是所求答案。

    注意a + b + c = 0的特判情况,还需要注意精度,题目要求1e-6,但是精度要达到1e-10以上才行,不然会WA,有点坑。

    【AC代码】

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    #include<iomanip>
    using namespace std;
    typedef long long ll;
    
    double s;
    double a,b,c;
    
    int main(){
        while(cin>>s){
            cin>>a>>b>>c;
            if(a + b + c == 0){
                cout<<1.0*s<<" "<<0<<" "<<0<<endl;
                continue;
            }
            cout<<setiosflags(ios::fixed)<<setprecision(18)<<s/(a+b+c)*a<<" "<<s/(a+b+c)*b<<" "<<s/(a+b+c)*c<<endl;
        }
    }
  • 相关阅读:
    Scala学习十二——高阶函数
    Scala学习十一——操作符
    Scala学习十——特质
    Scala学习九——文件和正则表达式
    Scala学习八——继承
    Scala学习七——包和引入
    Scala学习六——对象
    Scala学习五——类
    Scala学习四——映射和数组
    Spark Broadcast内幕解密:Broadcast运行机制彻底解密、Broadcast源码解析、Broadcast最佳实践
  • 原文地址:https://www.cnblogs.com/czsharecode/p/9665591.html
Copyright © 2020-2023  润新知