题意:度度熊最近对全排列特别感兴趣,对于1到n的一个排列,度度熊发现可以在中间根据大小关系插入合适的大于和小于符号(即 ‘>’ 和 ‘<’ )使其成为一个合法的不等式数列。但是现在度度熊手中只有k个小于符号即(‘<”)和n-k-1个大于符号(即’>’),度度熊想知道对于1至n任意的排列中有多少个排列可以使用这些符号使其为合法的不等式数列。
思路:
dp(i,j)
表示已经使用数字
1,2,3...i
以及
j
个小于符号所能构成的合理的不等式的数量。
那么我们考虑四种情况:
1、已经存在
把
c
插入到
2、已经存在
a<b
,现在插入
c
,
把
c
插入到
3、已经存在
a<b
,现在插入
c
,
把
c
插入到小于符号后面,形成
4、已经存在
b>a
,现在插入
c
,
把
c
插入到大于符号前面,形成
那么答案很明显了。
AC代码
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn = 1000+5;
int dp[maxn][maxn];
int main() {
int n, k;
while(scanf("%d%d", &n, &k) == 2) {
for(int i = 1; i <= n; i++) {
dp[i][0] = 1;
}
for(int i = 2; i <= n; i++) {
for(int j = 1; j <= min(i-1, k); j++) {
dp[i][j] = (dp[i-1][j-1] * (i-j) + dp[i-1][j] * (j+1))%2017;
}
}
printf("%d\n", dp[n][k]);
}
return 0;
}
如有不当之处欢迎指出!