第11回Lanqiaoカップ州大会のシミュレートされたスイングシーケンス(DP)

シーケンスの奇数アイテムがすべて前のアイテムより大きく、偶数アイテムがすべて前のアイテムよりも小さい場合、ウォブルシーケンスと呼ばれます。つまり、a [2i] <a [2i-1]、a [2i + 1]> a [2i]です。
  Xiao Mingは、長さがmで、各数値が1からnまでの正の整数であるスイングシーケンスの数を知りたいと考えています。

入力フォーマット

入力行には2つの整数mとnが含まれています。

出力フォーマット

答えを示す整数を出力します。答えが非常に大きくなる可能性があります。答えを10000で割った余りを出力してください。

入力例

3 4

出力例

14

サンプル概要

以下は、要件を満たすスイングシーケンスです。21
  2
  2 1 3
  2 1 4
  3 1 2
  3 1 3
  3 1 4
  3 2 3
  3 2 4
  4 1 2
  4 1 3
  4 1 4
  4 2 3
  4 2 4
  4 3 4

評価のユースケースの規模と規則

評価ケースの20%の場合、1 <= n、m <= 5
  、評価ケースの50%の場合、1 <= n、m <= 10
  、評価ケースの80%の場合、1 <= n、m <= 100 ;
  すべての評価ケースで、1 <= n、m <= 1000。

質問の意味:1からnの範囲で長さmのスイングシーケンスの数を見つける

アイデア:対象のデータ量によると、ブルートフォース検索は絶対に合格しません。この種のスイングは自然にDPに関連付けられますが、問題はこの変化をどのように表現するかです。ここでは、dp [i] [j]を使用して次のことを表現できます。

奇数:i番目の桁が最小の数jの場合、いくつ:

偶数:i桁目がjの最大数の場合:

iが偶数の場合:dp [i] [j] = dp [i-1] [j + 1] + dp [i] [j-1];(ここで、i番目の数字が表されると、最大数がjの場合、i桁目の最大数がj-1の場合と、i-1桁目の最小数がj + 1の場合(i桁目がjの場合)の2つに分かれます)

iが奇数の場合:dp [i] [j] =(dp [i-1] [j-1] + dp [i] [j + 1]);(ここでは、i番目の数字を表すものとして理解できます。最小数がjの場合、i桁目の最小数がj + 1の場合と、i-1桁目の最大数がj-1の場合(つまり、i桁目がjの場合)の2つに分かれます。

最後に、全長が奇数の場合はdp [m] [1]、偶数の場合はdp [m] [n]になります。

コード:

#include <iostream>
using namespace std;
int dp[1010][1010];
int main() {
    
    
    // m为长度,n为数的范围
    int m,n;
    cin>>m>>n;
    for(int i = 1; i <= n; i++)
        dp[1][i] = n - i + 1;
    for(int i = 2; i <= m; i++)
        if(i & 1)
            for(int j = n; j >= 1; j--)
                dp[i][j] = (dp[i-1][j-1] + dp[i][j+1]) % 10000;
        else
            for(int j = 1; j <= n; j++)
                dp[i][j] = (dp[i-1][j+1] + dp[i][j-1]) % 10000;
    int ans = m & 1 ? dp[m][1] : dp[m][n];
    cout<<ans;
    return 0;
}

おすすめ

転載: blog.csdn.net/weixin_43244265/article/details/105615084