[プログラミングの質問]不等式シリーズ
制限時間:C / C ++ 1秒、2秒、スペースの制限他の言語:C / C ++ 32M、他の言語64M
卒、1からnまでの順列のための全体配置における特定の最近の関心を負担、クマの程度は中間に見つかりました大小関係(すなわち、「>」と「<」)による挿入記号の上下適当に正規列番号不等式を行います。しかし、今手の程度は、シンボルの小さなkをクマすなわち(「<」「)、およびNK-1シンボルより1大きいが(すなわち、」>「)、クマの程度は、配列の数月1からnまでの任意の配置のために知ってほしいですこれらのシンボルを使用すると、それが合法的な不平等列です。
説明を入力します。
入力は二つの整数からなる行を含み、nおよびK(K <N≤1000)
出力説明:
出力条件の順列の数は、モジュロ2017への答えに満足です。
例1
入力
52
出力
66
思考
動的プログラミング:
DP [I] [J] iが任意jに配置された、すべての可能な小の記号で表しました。
第1の境界を考慮し、I = 0またはIの結果は、n 1にソートされ、J-1 =のみ可能です。
一般的な場合を考える、我々がdp [i]が[j]が、我々は、n-1のnに装置1に挿入できることを必要とします。
左または右端の最初のケースは、我々は挿入とj <したいし、<J>は、元の不平等に挿入することができますので。
後者の場合は、我々は、挿入したいj>は、その後、j>は、元の不平等に挿入することができます<右または左に極端な。
次に、一般式は、一般的な用語です。
dp[i][j] = dp[i][j-1] * (i+1)+dp[i - 1][j - 1] * (j - i)
DPを求め[i] [j]は全体のみラダーを通過することなく、平行四辺形の左上の領域にトラバースDP [I] [J]が必要です。
私の答え
#include <iostream>
using namespace std;
int main()
{
int n, k, dp[1001][1001];
cin >> n >> k;
for (int i = 1; i <= n; i++) {
dp[0][i] = 1;
dp[i][i + 1] = 1;
}
for (int i = 1; i <= k; i++) { //i为<个数,j-i-1为>个数
for (int j = i + 2; j <= i+n-k; j++) { //j为连续序列中的元素
dp[i][j] = (dp[i][j-1] * (i+1)+dp[i - 1][j - 1] * (j - i))%2017;
}
}
cout << dp[k][n];
return 0;
}