zoukankan      html  css  js  c++  java
  • 【*篇】烧水问题 打表找规律做法

    md打表题.
    按照贪心原则, 只要有烧开过的, 能热传递就热传递(反正没有热量损失)
    所以我们只需要按照以下流程图(唉这个图要是崩了别埋怨我, 我也不想的嘛←_←)做即是最优解:

    开始=>start: 开始
    结束=>end: 结束
    赋值=>operation: s=0,i=1
    烧水=>operation: s=s+(4200*(100-T[i])/n)
    遍历兑水=>operation: For j=i+1..n:T[i]=T[j]=(T[i]+T[j])/2
    完成=>condition: i<=n
    输出=>inputoutput: 输出s
    开始->赋值->完成(yes,right)->烧水->遍历兑水(right)->完成
    完成(no)->输出->结束
    

    然后就得到了一个(O(n^2))的做法.
    显然无法通过此题.
    但是我们可以打表得到一个数列... 前几项差不多长这样...

    [420000,315000,262500,229687.5,206718.75,189492.1875,175957.03125,164959.716796875 ]

    然后找规律即可.

    根据所学数列相关知识, 我们认为这些项之间的差/比应该会有一定的关系...
    但是不管是差一下还是比一下都找不出什么显而易见的规律...
    我们发现烧水的时候是有(/n)这种操作的..
    我们就(*n)逆回去再看..
    我们便可以设数列({B_i}), 满足(B_i=i*s_i)..
    然后再比就比出规律了..
    发现(frac{B_{i+1}}{B_i}=frac{2i+1}{2i}=1+frac{1}{2i}=frac{s_{i+1}*(i+1)}{s_i*i})..
    我们就可以化简出(O(n))的递推式(s_{i+1}=frac{(1+frac{1}{2i})*s_i*i}{i+1})
    然后这样已经足以通过此题了..

    #include <cstdio>
    int main(){
        int n;scanf("%d",&n);
        double s=420000;
        for(int i=1;i<n;++i)
            s=((1+1.0/(i+i))*s*i)/(i+1);
        printf("%.2lf",s);
    }
    

    但是式子长得不是很好看..太啰嗦..
    我们可以收拾一下?
    (s_{i+1}=s_i*frac{i+0.5}{i+1})
    然后加上一点点奇怪的压行技巧..就会出现warning...
    就可以做成这样

    #include<cstdio>
    main(){double n,s=4.2e5,i=1;scanf("%lf",&n);for(;i<n;)s*=(i+0.5)/++i;printf("%.2lf",s);}
    

    我应该是做不到更短了...

    打表题做起来应该很愉快才对~OvO

  • 相关阅读:
    win10安装nodejs,修改全局依赖位置和环境变量配置
    JavaScript判断两个对象内容是否相等
    JS判断是否是数组
    Js判断值是否是NaN
    typeof方法重写(区分数组对象)
    JS实现图片懒加载
    输入url到展示页面过程发生了什么?
    html如何在服务端跑起来
    nuxt怎么打包
    如果scss引用了字体图标文件该怎么打包
  • 原文地址:https://www.cnblogs.com/enzymii/p/8412207.html
Copyright © 2011-2022 走看看