[6州試験2017]願いは問題の解決策を壊すことです(DPを期待)

タイトル説明

B氏ゲームをプレイし、ゲームから成る  n個の ランプおよび  N  組成を切り替え、その所与の  N  ランプの初期状態を、より添字  1  の  nは 正の整数。

各状態は、我々が使用する、オンとオフの二つの光を持っている  と、ライトが明るく示すために、1を  0ライトが消灯している、ゲームの目的は、すべてのライトを出している作ることであることを示しています。

しかし、場合の動作  タイムスイッチはI、すべての番号  約数は、I(含む  1及び  I)ランプの状態、すなわち、光からオフになる、または光オフに、変更されます。

B氏は、このゲームは非常に困難見つかったので、すべてのライトが消されるまで、このような戦略の考えは、それぞれが、そのような確率としてスイッチを操作します。

操作の数は、この戦略の多くは、Bは-JUNそのような最適化を考える必要がありました。現在の状況は、操作がで少なくすることができるならば  、Kすべてのライトが消灯スイッチ、それから彼はもはや、操作のダイレクト選択操作方法の最小数(この戦略は明確に以下のランダムでないでしょう  k個の ステップ)これらのスイッチの操作。

Bさん(すなわち第1のランダム動作、より少ない最後に応じてこの戦略を知りたい  k個の 操作の所望の数の操作の方法の操作の最小数を使用して、ステップ)。

この期待は大きいかもしれないが、B氏は、この期待がで乗算されていることがわかる  nは 整数でなければならない階乗ので、彼が唯一の整数知っている必要があります  100003の モジュロ後の結果を。

 

$ソリューション:$

神グッド。

:まず、最適な戦略は推測を描画することは困難ではないようにする方法を検討し、動作させるために右から左にそれを遮断してください。

感度は、多数の小さな数を制御することができない確かに、それを理解し、数値の各セットは、(かかわらず、現在の状態の)特定の操作の影響を受けました。遅かれ早かれによって大と点灯の数が、衝撃ので、次の処理を決定するために状態を押した方がよいと判断されます。

さらに、これは、明らかに各ランプの最大動作時間であり工程の最適な数はnより大きくない必要があるように。

状態ごとに、最適戦略が一意に決定され、その後、我々は、それぞれの状態を表すためにオペランドの最適な戦略で使用できます。

状態の$ I $の適切な操作は、$ I $が$になった場合には、I-1 $。誤って行うと逆に、それは$ I + 1 $になります。

[i]は$ $ステップの所望の数からランダム、設定された$のDPの一部$ I $ I-1 $必要です。

前推論は、それが入手が容易である:$のDP [I] = 1 \回\ FRAC {I} {N} + \ FRAC {NI} {N} \回(DP [I] + DP [I + 1] + 1)$

ステップジャンプによると、押し間違ったバック$ I + 1 $、また[i]が+ 1 $ $ I-1 $にジャンプするには$ DP [I + 1] + DPを必要としています。

簡略化の所与$ DP [I] = \ FRAC {(NI)DP [I + 1] + N} {I} $、$の\合計$を求めて、次に実行されるステップの数と最適な戦略は、スペルします答えます。

#include <cstdioを> 
する#include <iostreamの> 
する#include <CStringの> 
する#include <ベクトル> 
名前空間STDを使用して、
CONST int型N = 1E5 + 5。
typedefの長い長いLL。
CONST LL MOD = 1E5 + 3。
N INT、K、[N]。
ベクター<整数>事実[N]。
LLのFAC = 1、ANS、DP [N]。
LLのqpow(LLのX、LLのY)
{ 
    LL RES = 1; X = X%MOD。
    一方、(Y)
    { 
        IF(Y&1)RES =の解像度* X%MOD。
        X = X * X%MOD。
        Y >> = 1。
    } 
    RESを返します。
} 

ボイドINI()
{ 
    (INT X = 1; X <= nであり; x ++)についての
    { 
        FAC * = 1LL * X、FACの%= MOD。
        (私は++; iは= xを<* I 1 = INT)のために
        {
            (Xの%i)を続行。
            場合事実(私は== xと*)[X] .push_back(I)。
            他の事実[X] .push_back(I)、事実[X] .push_back(X / I)。
        } 
    } 
} 

int型のmain()
{ 
    scanf関数( "%D%dの"、&N、&K)。
    INI(); 
    (I 1 = int型、iが<= N; iが++)のため
        のscanf( "%dの"、および[I])。
    INTステップ= 0。
    以下のために(INT I = N; I; i--)
    { 
        IF(![i])と続けます。
        ステップ++; 
        (INT J = 0; J <事実[I] .size(); J ++)のための
            [ファクト[I] [J]] ^ = 1; 
    } 
    であれば(ステップ<= K)を
    { 
        のprintf( "%LLDする\ n"、1LL *ステップ* FACの%のMOD)。
        0を返します。
    }
    (私は、n = int型のために、
    { 
        LL INV = qpow(I、MOD-2)。
        DP [I] =(1LL *(NI)* DP [I + 1]%のMOD + N%のMOD)%MOD。
        (DP [I] * = INV)%= MOD。
    } 
    のために(iは= K + 1がint; iは=ステップを<; iは++)
        (ANS + = DP [I])%= MOD。
    (ANS + = K)%= MOD。
    (ANS * = FAC)%= MOD。
    coutの<< ANS <<てendl; 
    0を返します。
}

 

おすすめ

転載: www.cnblogs.com/Rorschach-XR/p/11619177.html
おすすめ