解決
ステート設計
セット\(F_ {I、J} \) の(1 \)\に(I \)\配置され、その\(J \)\(\テキスト{ '<' } \) プログラムの数。
状態遷移
試す\(I \)へ進む\(I + 1 \)は、物質をすると考えられる(I + 1 \)は\配列のどの位置に挿入されています。
- あなたが左に挿入した場合、大なり記号(追加されます\(1 \)のケース)
- 右のほとんどに挿入した場合、少ない数(以上追加します\(1 \)の場合)
- あなたが間に挿入した場合より少なくより、少ないよりも、新しい番号の当量よりも大きく(未満より大きい数を生成破壊する\(J \)の場合)
- 数インサートとの間に1よりも大きい場合には、製造、より数の大きい破壊大なり、少ない数未満新しい番号の等価より(\(I - 1 - J \)ケース)
要約すると:
- そこ\(J + 1 \)場合、すなわち、数の増加よりも大きい(F [I + 1] \ [j]が\ F [I] [J] *(J + 1)\取得)
- そこ\(I - J \)以下より数を増やす場合、\(F [I + 1] [J + 1] \取得F [i]の[j]は*(I - J)\)
コード
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1005, P = 2015;
int n, K, f[N][N];
int main() {
scanf("%d%d", &n, &K);
f[1][0] = 1;
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
(f[i + 1][j] += f[i][j] * (j + 1)) %= P;
(f[i + 1][j + 1] += f[i][j] * (i - j)) %= P;
}
}
printf("%d\n", f[n][K]);
}