• P1984 [SDOI2008]烧水问题(具体证明)


    传送门

    我见过的第二恶心的题,第一是糖果传递...

    以下是一堆具体的证明,自己想的,可能考虑不周,不想看也可以直接看结论


    首先有一个很显然的贪心,烧开的水要尽量把热量传递出去

    所以有一个比较显然的方法:每杯水烧开后都与下一杯水热传递,平衡后再把剩下的温度与更后面一杯水热传递,这样一直下去...

    十分显然把热量传递出去比不传递出去要更优

    具体证明:设下一杯水温度为 $t_1$,此时上一杯水已经烧开,为$t_{max}$

    如果它们之间进行热传递,那么下一杯水的热量就变成 $frac{t_1+t_{max}}{2}$

    显然温度会更高,所以烧开所需热量更少,答案会更优,并且可以容易推广到多杯水的情况

    然后热量传出去了,按什么顺序烧开他们也是关键

    方法:把温度从大到小排序,优先烧温度大的水再把热量传下去会更优

    证明:设第一杯水温度为 $t_1$ ,第二杯水温度为 $t_2$,且 $t_1>t_2$

    如果我们先烧第一杯水,那么需要升高的温度为 $t_{max} - t_1$ 

    然后第一杯水烧开后再把热量传给第二杯水,第二杯水温度变成 $frac{t_2+t_{max}}{2}$

    把第二杯水烧开需要升高的温度为 $t_{max} - frac{t_2+t_{max}}{2}$

    因为水质量一样,所以升高的温度可以直接相加,化简得$frac{3}{2}t_{max} - t_1 -frac{t_2}{2}$

    因为水的质量一样,所以温度的升高多少就相当于热量的消耗多少

    如果我们先烧第二杯水再传温度给第一杯水再烧第一杯水

    经过同样的方法可以算出总共升高的温度为$frac{3}{2}t_{max} - t_2 -frac{t_1}{2}$

    因为 $t_1>t_2$ ,所以第一种方案更优,此结论用同样的方法也能推广到多杯水的情况


    所以总结一下,就是优先烧温度大的水,然后把热量尽量传出去

    知道了方案,每杯水消耗的热量自己找找规律就出来了

    设 $f_n$ 表示第 n 杯水烧开消耗的热量

    那么 $f_n=f_{n-1}*[1-frac{1}{2}(n-1)]$

    代码不解释

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    int n;
    double ans,now=420000.0;
    int main()
    {
        n=read(); now/=n;
        for(int i=1;i<=n;i++) ans+=now,now*=(1-0.5/i);
        printf("%.2lf",ans);
        return 0;
    }

     

  • 相关阅读:
    JavaScript寄生组合式继承分析
    常用的css命名规则:
    jshint配置(js检查)
    当页面关闭或刷新时提示用户
    Ionic 开发环境搭建
    VS Code前端开发利器-常用快捷键
    Uploadify 上传插件引起Chrome崩溃解决方法
    “全栈工程师”的尴尬
    redis集群升级,数据迁移及校验
    K-means
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9828420.html
Copyright © 2020-2023  润新知