LUOGU 1984:数論再帰で[SDOI2008]沸騰の水問題

タイトル

LUOGU 1984

説明:

Nカップ1kgの中に含まれる水の総質量、水質の各カップ(1 / N)kgであり、初期温度が0℃です。今、私たちは、沸騰する水のすべてのカップを持っている必要があります。私たちは、水のいずれかのガラスで加熱することができます。水必要なエネルギーのT℃のガラスの高温] C(4200 *のT / N)J、前記 "J" エネルギー単位 "ジュール"。水のガラスは温度が100℃に達した場合たら、その後、水温のこのガラスは、もは​​や我々は茹でされたこの水のガラスを考える、上昇し続けることはできません。ガラスカップに直接水が沸騰する場合は明らかに、必要とされる全エネルギーは(4200 * 100)J.であります

沸騰水の過程で、我々はいつでも水の異なる温度の2杯の間の熱伝達を操作することができます。水の低温ガラスからの水のガラスにのみ、より高い温度の熱伝達。熱伝達動作は、水より高い温度の元のガラスは常に水の元の低温ガラス高温の低下温度と等しくなるように水質の2杯後、同じです。

水の同じ2つのカップの温度と、熱伝達が直ちに停止されます。

問題を単純化するために、我々は想定しています。

図1に示すように、加熱なしまたは熱伝達動作、水の温度は変化しません。

2は、すべての水を加熱に費やされるエネルギーが吸収され、カップはエネルギーを吸収しません。

図3に示すように、熱は、常に互いに混合決してN-のカップ、グラスを介して転送されます。

図4に示すように、保存される熱エネルギーを伝達し、いかなる熱損失は存在しません。

この問題では、すべてその上に再び沸騰する水の少なくともカップを持っている唯一の要件は、最終的な温度を必要とすることなく水のすべてのカップは100℃です。次のように我々は、沸騰に水の2つのカップを使用することができる:最初に水のガラスは、100℃に加熱した】C、エネルギーコスト(* 100/2 4200)J、及び熱伝達のための水の2つのカップを、50℃までその温度まで] Cとなっています。最後に、元の水の100℃のガラスを100℃に加熱したに加熱されていない。] C、エネルギーコストJが、この時点で水の2個のカップが上煮沸され、現在の温度100℃、カップ、カップ50℃(* 50/2 4200)総エネルギーコストは、Jが25%少ないエネルギーを費やした(* 75 4200)J、所望の比率は、直接(* 100 4200)を沸騰です。

あなたの仕事は、プログラムの最適な動作を設計することである水のn個の眼鏡は、少なくとも全エネルギー必要な、最小のオーバー沸騰するようなものである\(1 \ leqslant N \のleqslant 3000000 \)を

分析

タイトルの数を見てみると、カザフスタンは、法遵守の友人を見つけます。

エネルギー
1 \(F [1] = 420000 \)
2 \([2] = F [1] * \ FRAC {3} {4} Fを= [1] * \ FRAC * {2-1(2)} {(2×2)} = 315000 \ F)
3 \([3] = F [2] * \ FRAC {5} {6} fは= [2] * \ FRAC * {3-1(2)} {(2 * 3)} = 262500 \ F)
... ...
\(N \) \(F [N] = F [N-1] * \ FRAC {(2 * N-1)} {(2 * N)} \)

したがって再帰式は:
\ [F [N-] = F [1-N-] * \ FRAC {(2-N- * 1)} {(N-2 *)} \]

証拠としてではなく、(エスケープします。

コード

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e6+10;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}

double f[maxn];
int main()
{
    int n;read(n);
    f[1]=420000.00;
    for (int i=2; i<=n; ++i) f[i]=f[i-1]*(2*i-1)/(i<<1);
    printf("%.2f\n",f[n]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/G-hsm/p/11365644.html