洛谷 P1984 [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

虽然标签是数学,但它仍然是个贪心问题

既然要使烧水的总能量最少,那就**少烧水**,所以我们可以用烧开了的水传递热量,
把它的热量**尽可能的都传给**剩下的几杯,而且一杯水烧开了一次之后,就不用管最终温度了,
我们就算把它的温度传递至只剩0(虽然不可能,∵每次/2)也不会对最终结果产生任何影响

我们把第一杯烧开了之后往后传它的热量,再烧开下一杯,以此类推,相邻两杯的热量是
有一定的关系的,然后,可以推相邻两个的所需热量公式(也就是它们的倍数关系),
看这个关系是几倍即可
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int n;
double ans1,ans;

int main()
{
    //freopen("water.in","r",stdin);
    //freopen("water.out","w",stdout);

    scanf("%d",&n);

    double t=100.0,m=4200.0;
    ans1=m*t/n;//第一杯水,需要升高100℃
    ans+=ans1; 

    for(int i=2;i<=n;i++) //2~n杯水
    {
        ans+=ans1*(2*(i-1)-1)/(2*(i-1));
        ans1=ans1*(2*(i-1)-1)/(2*(i-1)); //随时更新“上一杯水”所需要的热量 
        //第i杯水烧开所需能量 是 第i-1杯水烧开所需能量*(2*(i-1)-1)/(2*(i-1))


//ans1*=(2*(i-1)-1)/(2*(i-1));不能这样写,因为“/”是下取整,
//如果得到的是分数的话,很可能取到,毕竟不能像"3/4"一样存,3/4得到的是 商:0
//如果取到0,那ans1就变为0了,但是,如果把ans1乘过来写(ans1* (2*(i-1)-1)/(2*(i-1)))
//根据从左往右的运算原则 (2*(i-1)-1)/(2*(i-1))<1,所以一定不可能商为0 
    } 

    printf("%.2lf",ans);

    return 0;
}
/* 32   83451.27 */
基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值