zoukankan      html  css  js  c++  java
  • [SDOI2008]烧水问题

    题目描述

    把总质量为1kg的水分装在n个杯子里,每杯水的质量均为(1/n)kg,初始温度均为0℃。现需要把每一杯水都烧开。我们可以对任意一杯水进行加热。把一杯水的温度升高t℃所需的能量为(4200*t/n)J,其中,“J”是能量单位“焦耳”。如果一旦某杯水的温度达到100℃,那么这杯水的温度就不能再继续升高,此时我们认为这杯水已经被烧开。显然地,如果直接把水一杯一杯地烧开,所需的总能量为(4200*100)J。

    在烧水的过程中,我们随时可以在两杯温度不同的水之间进行热传递操作。热量只能从温度较高的那杯水传递到温度较低的那杯水。由于两杯水的质量相同,所以进行热传递操作之后,原来温度较高的那杯水所降低的温度总是等于原来温度较低的那杯水所升高的温度。

    一旦两杯水的温度相同,热传递立刻停止。

    为了把问题简化,我们假设:

    1、没有进行加热或热传递操作时,水的温度不会变化。

    2、加热时所花费的能量全部被水吸收,杯子不吸收能量。

    3、热传递总是隔着杯子进行,n杯水永远不会互相混合。

    4、热传递符合能量守恒,而且没有任何的热量损耗。

    在这个问题里,只要求把每杯水都至少烧开一遍就可以了,而不要求最终每杯水的温度都是100℃。我们可以用如下操作把两杯水烧开:先把一杯水加热到100℃,花费能量(4200*100/2)J,然后两杯水进行热传递,直到它们的温度都变成50℃为止,最后把原来没有加热到100℃的那杯水加热到100℃,花费能量(4200*50/2)J,此时两杯水都被烧开过了,当前温度一杯100℃,一杯50℃,花费的总能量为(4200*75)J,比直接烧开所需的(4200*100)J少花费了25%的能量。

    你的任务是设计一个最佳的操作方案使得n杯水都至少被烧开一遍所需的总能量最少。

    输入输出格式

    输入格式:

    输入文件只有一个数n。

    输出格式:

    输出n杯水都至少被烧开一遍所需的最少的总能量,单位为J,四舍五入到小数点后两位。

    输入输出样例

    输入样例#1: 复制
    2
    输出样例#1: 复制
    315000.00

    说明

    1≤n≤50000

    思路

    需要推个式子,下面是来着洛谷的题解

    推导:设沸腾温度为a
    则第一杯温度为a,需要加热t1=a 
    第二杯可以中和的最高温度为a/2,需要加热t2=a/2 
    第三杯可以中和的最高温度为t3=(a/4+a)/2=5a/8,需要加热t3=3a/8 
    第四杯可以中和的最高温度为t4=((a/8+5a/8)/2+a)/2=11a/16,需要加热t4=5/16 
    则t3/t2=3/4=1-1/4,  t4/t3=5/6=1-1/6
    继续推导得t(n+1)/t(n)=1-1/2n

    代码

     1 #include<cstdio>
     2 double n,ans;
     3 int main(){
     4     scanf("%lf",&n);
     5     double c=420000.0/n;
     6     for(int i=1;i<=n;i++){
     7         ans+=c;
     8         c*=(1.0-0.5/i);
     9     }
    10     printf("%.2lf",ans);
    11     return 0;
    12 }
  • 相关阅读:
    写给QA/软件测试新人
    互联网产品线上故障管理规范
    爬了世纪佳缘后发现了一个秘密,世纪佳缘找对象靠谱吗?
    网传美团今年应届生年薪 35w+,严重倒挂老员工,为什么互联网大厂校招的薪资一年比一年高?...
    MySQL大表优化方案
    步入AI领域2年连升3级,我只是找对了学习方法而已……
    BZOJ 4008 亚瑟王(概率DP 奥妙重重)
    BZOJ 4318 OSU! (概率DP)
    BZOJ 3812 主旋律 (状压DP+容斥) + NOIP模拟赛 巨神兵(obelisk)(状压DP)
    BZOJ 4145 [AMPPZ2014]The Prices (状压DP)
  • 原文地址:https://www.cnblogs.com/J-william/p/7725823.html
Copyright © 2011-2022 走看看