http://acm.hdu.edu.cn/showproblem.php?pid=2583
题意: 输入 n m 问n组成的全排列中 有m个小于号的排列的个数
思路:
我们设
n(<=100)个数 1,2,...,n的排列有n!个 ,有k个小于号的有 f[n][k]个。
假如
a[1],a[2],...,a[n-1],是n-1个数的排列,有 k个'<'
把 n插入,有n个位置可以插入,
把 n插入到a[1]的前面, '<'没有增加 , 1个位置
如 a[i]<a[i+1], 把 n插入到a[i+1]的前面, '<'没有增加 , k个位置
插入到其他位置 '<'增加
因此
f[n][k]=f[n-1][k]*(k+1) + f[n-1][k-1] *(n-k)
这个状态转移方程的初始状态:dp[n][0] = dp[n][n-1] = 1,因为分别只有为严格递增和严格递减一种情况。
#include<cstdio>
#define N 101
#define inf 2007
int dp[N][N];
int main()
{
int n,k,i,j;
for(i=0;i<N;i++)
{
dp[i][0]=1;
dp[0][i]=0;
}
for(i=1;i<N;i++)
for(j=1;j<N;j++)
dp[i][j]=(dp[i-1][j]*(j+1)+dp[i-1][j-1]*(i-j))%inf;
while(scanf("%d%d",&n,&k)!=EOF)
{
printf("%d\n",dp[n][k]);
}
return 0;
}