6

配列内の LIS (最長増加部分列) の計算は、非常に有名な動的計画法の問題です。ただし、すべてのチュートリアルでは、最初に DP の概念を使用せずに再帰的なソリューションを示し、次にボトムアップ DP (反復ソリューション) を適用して解決します。

私の質問は:

再帰的なソリューション自体で メモ化をどのように使用しますか。ただのメモ化ではなく、一次元配列を使ったメモ化。

いくつかの調査を行いましたが、関連するものは何も見つかりませんでした。再帰的なメモ化について質問された箇所は1 & 2の2 箇所ありますが、そちらの解決策はメモ化に 2D Map / Array を使用しています。

とにかく、1D配列でソリューションをメモすると、間違った出力が得られます。これが私がしたことです:

int lis(int idx, int prev)
{
    if(idx >= N)
        return 0;

    if(dp[idx])
        return dp[idx];

    int best_ans = lis(idx+1, prev);

    int cur_ans = 0;
    if(arr[idx] > prev)
    {
        cur_ans = 1 + lis(idx+1, arr[idx]);
    }
    int ans = max(best_ans, cur_ans);
    dp[idx] = ans;
    return ans;
}

int main()
{
    // Scan N 
    // Scan arr

    ans = lis(0, -1));
    print ans;
}

このソリューションが間違った出力を与える理由はわかっていますが、次のようになります。

以前の値に基づいて、与えられたインデックスに対して複数のソリューションが存在する可能性があります。

しかし、1D配列を使用してそれを行う方法を知りたいです。

すべての DPのトップダウンソリューションをボトムアップに、またはその逆に再構成できることを読んだので、ソリューションを知りたいと思っています。

誰かが同じことについて何らかの洞察を提供できれば、非常に役に立ちます。

前もって感謝します。

4

3 に答える 3